diff --git a/ROADMAP.MD b/ROADMAP.MD index 43802309..15b263f8 100644 --- a/ROADMAP.MD +++ b/ROADMAP.MD @@ -8,6 +8,7 @@ out how to make a **rfc** in the [rfc](https://github.com/simple-lang/rfcs) rep The roadmap is divided into sections - [General](#general) - [Modules](#modules) +- [Extended Modules](#extended-modules) - [Environments](#environments) ### General @@ -47,13 +48,18 @@ build, installation, features e.t.c - [ ] build script should create a .a archive for statically linking simple-lang runtime on linux os - [ ] build script should create a .a archive for statically linking simple-lang runtime on mac os - [ ] build script should create a .a archive for statically linking simple-lang runtime on haiku os -- [ ] add a new flexible keyword to lock a variable to a particular declaration similar to **final** to prevent re initializing +- [x] add a new flexible keyword **final** to lock a variable to a particular to prevent re initializing - [ ] allow strong and weak typing to prevent inconsistent and conflicting initialization - [ ] add directive for compiler notation in [] format - [ ] VM should treat really really large number ad big as 10e+50 -- [x] allow calling file with explicit module name translating to literal e.g `call simple.core.String` = `call "simple\core\String.sim"` -- [ ] Add strict equality `===` and `!==` +- [x] allow calling file with explicit module name translating to literal e.g `call simple.core.String` = `call "simple\core\String.sim" ? simple.core` [PR](https://github.com/simple-lang/simple/pull/34) +- [ ] Add strict equality `==` and `!=` and weak equality `===` and `!==` - [ ] Add the `**` operator +- [ ] allow creating multi block i.e blocks with the same name but different parameter length +- [ ] use the Karatsuba Algorithm for pure multiplication of large numbers +- [ ] reformat the way the error are thrown in the console and web +- [ ] allow '*' to call all the file in a folder e.g simple.core.* +- [ ] update windows build file Windows-Build.bat to use main build C/C++ toolchain to build environment apps ### Modules @@ -76,12 +82,22 @@ issue related to the module - [ ] make curl request and accept both http and https protocols - [ ] build a web module for cgi and template base development - [x] Math module to treat any form of basic math operation + - [ ] add various multiplication method in the math module including Karatsuba algorithm + - [ ] include a block that fetch the number of factors a number have and another that return a list of a number factors - [x] date and time module - [ ] conversion module to convert between objects and types - [ ] system, simplex and runtime module - [x] create the hash module - [x] a basic encrypt and decrypt module that uses keys and IV - [ ] port murmur hash C library to simple-lang +- [ ] implement ncurses for use in simple-lang + +### Extended Modules + +Modules which are not part of the standard module that comes distributed with simple-lang. These modules are only avilable for use by downloading the release versions or using the simple-lang module manager **modular** to install them. These sources are hosted in a seperate repository but in the same organization. [source here.](https://github.com/simple-lang/extended-modules/) + +- [ ] create material and native os extended module for fulltick GUI module +- [ ] a module that convert fultick Widget to HTML element ### Environments diff --git a/build/Windows-Build.bat b/build/Windows-Build.bat index b0b9d813..2f1d6410 100644 --- a/build/Windows-Build.bat +++ b/build/Windows-Build.bat @@ -872,13 +872,13 @@ REM MINIFY ALL THE MODULE SOURCE (.sim) only if !EXEC_TYPE!=="install" ( if exist "!INSTALLATION_FOLDER!\%VERSION%\modules" ( echo modules:minifying: starting simple sources minification in !INSTALLATION_FOLDER!\%VERSION%\modules directory - !INSTALLATION_FOLDER!\%VERSION%\bin\simple.exe !MINIFICATION_PROGRAM! --source !INSTALLATION_FOLDER!\%VERSION%\modules -y + REM !INSTALLATION_FOLDER!\%VERSION%\bin\simple.exe !MINIFICATION_PROGRAM! --source !INSTALLATION_FOLDER!\%VERSION%\modules -y ) ) if !EXEC_TYPE!=="debug" ( if exist "..\..\%SIMPLE_DEBUG_VERSION%\modules" ( echo modules:minifying: starting simple sources minification in ..\..\%SIMPLE_DEBUG_VERSION%\modules directory - ..\..\%SIMPLE_DEBUG_VERSION%\bin\simple.exe !MINIFICATION_PROGRAM! --source ..\..\%SIMPLE_DEBUG_VERSION%\modules -y + REM ..\..\%SIMPLE_DEBUG_VERSION%\bin\simple.exe !MINIFICATION_PROGRAM! --source ..\..\%SIMPLE_DEBUG_VERSION%\modules -y ) ) echo modules:minifying: minification complete diff --git a/examples/intermediate/consoleprogressbar.sim b/examples/intermediate/consoleprogressbar.sim index c5101b0e..b6d6b6e2 100644 --- a/examples/intermediate/consoleprogressbar.sim +++ b/examples/intermediate/consoleprogressbar.sim @@ -10,54 +10,42 @@ * @Time - 09:42 PM */ -call "simple/utilities/Console.sim" +call simple.utilities.Console -limit = 10000 +PBSTR = "||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||" +PBWIDTH = 60 -@"A Progress That count from 0 to "+limit -@"Drawback is it blink indefinitely" - -for a = 0 to limit { - display char(13)+" currently counting at "+a -} -@""+crlf - -@"To prevent blinking we flush the console standard output" -@"Watch closely the same count from 0 to "+limit+" without blink : fails" - -for a = 0 to limit { - display char(13)+" currently counting at "+((a/limit)*100)+"% " - __flush_console() -} -@""+crlf - -@"A progress bar using #######" -for a = 0 to limit { - val = ((a/limit)*100) - display "Downloading at "+val+"% ["+joinChar("#",val)+"]"+char(13) - __flush_console() -} -@""+crlf - -@"A progress bar 2 using #######" -progressBar = "...................................................................................................." -for a = 0 to limit { - val = ((a/limit)*100) - display char(269)+"Downloading at "+val+"% ["+joinChar2(progressBar,val)+"]" -} -@""+crlf - -block joinChar(character,times) - fchar = "" - for b = 0 to times { - fchar+=character +block main() + display "Enter Your Limit : " read limit + @"A Progress That count from 0 to "+limit+" in different styles " + printProgress(limit,"=") + + @"" + for a = 0 to 200 { + printProgress_1((a * 100/200)) } - return fchar -block joinChar2(character,times) - for b = 0 to times { - character[b] = "#" +block printProgress(length,indicator) + progress = 0 + while progress < length { + barWidth = 100 + + stdout.print("[") + pos = (progress * barWidth ) / length + for i = 0 to barWidth { + if i < pos stdout.print(indicator) + elif i == pos stdout.print(">") + else stdout.print(" ") end + } + stdout.print("] "+pos+" %% of "+progress+"\r") + stdout.flush() + + progress ++ } - return character - +block printProgress_1(percentage) + val = percentage * 100 + lpad = percentage * PBWIDTH + rpad = PBWIDTH - lpad + stdout.vprintf(["\r#{1}%#{2} [#{3}#{4}]", val, lpad, PBSTR, rpad, ""]) + stdout.flush() \ No newline at end of file diff --git a/examples/modules/consoledemo.sim b/examples/modules/consoledemo.sim index 9e952813..09806db5 100644 --- a/examples/modules/consoledemo.sim +++ b/examples/modules/consoledemo.sim @@ -1,22 +1,55 @@ #1 call simple.utilities.Console - +call simple.core.List block main() + obj = new TestObject + obj1 = new CustomStringObject + obj2 = new NoToString + list = new List(["This only for #{2} mudule test ignore #{1}\n", "Typos", "Console"]) + #the stdout - stdout.println("\tHello World") + stdout.println("\tHello World") #string + stdout.println(1 * 2 + 23 + 65 / 1 * 767) #number + stdout.println([1,"26",256,"tes", "2354"]) #list + stdout.println(null) #null + stdout.println(obj) #object inherit simple.core.Object + stdout.println(obj1) #object 1 has a custom toString() + stdout.println(obj2) #object 2 has no toString() block stdout.print("Yes you the boss\n") + stdout.printfc(ConsoleColor.BLUE()," The string in blue - STD OUT \n") stdout.vprintf(["#{1} #{2} #{3} bit #{4} of version #{5}\n", "this", "is", 8 * 8, "simple-lang", getSimpleVersion()]) #the std err stderr.println("This is an error") + stderr.println(1 * 2 + 23 + 65 / 1 * 767) #number + stderr.println([1,"26",256,"tes", "2354"]) #list + stderr.println(null) #null + stderr.print(obj) #object inherit simple.core.Object + stderr.print(obj1) #object 1 has a custom toString() + stderr.println(obj2) #object 2 has no toString() block stderr.print("This is an error in print\n") + stderr.vprintf(list) + stderr.printfc(ConsoleColor.RED()," The string in red - STD ERR \n") #global block println(stdout, "print with newline Hello World globally") print(stdout, "print Hello World globally") - printfc(stdout,ConsoleColor.RED()," The string in red") + @_vformatf(["\nJust for #{1} console ", "Testing"]) + printfc(stdout,ConsoleColor.YELLOW()," The string in yellow") + + +class TestObject : Object + +class CustomStringObject + + block toString() + return "[CustomStringObject:toString():it custom toString()]" + +class NoToString + + num = 1 nim = 2 /*[obsolute] block main_old() diff --git a/examples/syntax/final.sim b/examples/syntax/final.sim new file mode 100644 index 00000000..661c9ab6 --- /dev/null +++ b/examples/syntax/final.sim @@ -0,0 +1,54 @@ + +/* + KEYWORD : final + FUNCTIION : To lock a variable to only one initialization, to prevent assigning new value to a + variable that not meant to change value. + USE CASE : In the @File Console module the **stdout** is a final variable to prevent initializing it to something + else to prevent runtime error while using the @File Console blocks and classes +*/ + +flexibleDuck = "This is a changable variable anytime any where" +final finalVar = "This remain throughout execution" +final aClass = new AClass +try { + aClass.setPath("a new path") +catch + @__err__ +} + +@flexibleDuck +@finalVar + +flexibleDuck = "Well the duck is an animal" +try { + finalVar = "Try changing to another value" +catch + @__err__ +} + +@aClass.getPath() +@flexibleDuck +@finalVar +@InerFinal() + + +block InerFinal() + final innerFinal = "inner final variable" + notFinal = "desi" + + notFinal = "indoian" + innerFinal = "Try changing it throw an error" + + @innerFinal + +class Parent + + final path = "foo ? bar ? whatever " + + block getPath() + return path + +class AClass : Parent + + block setPath(p) + this.path = p \ No newline at end of file diff --git a/modules/dynamic_modules/consoler/consoler.c b/modules/dynamic_modules/consoler/consoler.c index b348e716..14b79ee4 100644 --- a/modules/dynamic_modules/consoler/consoler.c +++ b/modules/dynamic_modules/consoler/consoler.c @@ -95,11 +95,12 @@ void std_print(void *pointer) void program_flush_console(void *pointer) { - if ( SIMPLE_API_PARACOUNT != 0 ) { - SIMPLE_API_ERROR(SIMPLE_API_BADPARATYPE); + if ( SIMPLE_API_PARACOUNT != 1 ) { + SIMPLE_API_ERROR(SIMPLE_API_MISS1PARA); return ; } else { - fflush(stdout); + FILE* std_output = (FILE*) SIMPLE_API_GETCPOINTER(1,"SIMPLE_CONSOLE_"); + fflush(std_output); return; } } diff --git a/modules/simple/utilities/Console.sim b/modules/simple/utilities/Console.sim index f8256608..89c124a8 100644 --- a/modules/simple/utilities/Console.sim +++ b/modules/simple/utilities/Console.sim @@ -13,16 +13,14 @@ #author - Azeez Adewale */ -module simple.utilities - -/* - call the @File ConsoleColor.sim which hold all the type of color for the foreground and background - of the console. The dynamic module @DynamicModule Consoler is also called in the file. -*/ call simple.utilities.ConsoleColor +call simple.core.List -/*@Prefix +/*@Prefix + call the @File ConsoleColor.sim which hold all the type of color for the foreground and background + of the console. The dynamic module @DynamicModule Consoler is also called in the file. + call the @Class List for the list class */ /* @@ -90,31 +88,39 @@ __stdin = __init_stdin() /* Create an instance of the @Class stdout for printing and outputing to the standard output */ -#final - to become final when final keyword has been impleented -stdout = new stdout(__stdout) +final stdout = new stdout(__stdout) /* Create an instance of the @Class stderr for printing and outputing to the standard error and diagnostic output */ -#final - to become final when final keyword has been impleented -stderr = new stderr(__stderr) +final stderr = new stderr(__stderr) /* - + The forgreound/text color of text of the standard output */ __stdForegroundColor = ConsoleColor.NONE() /* - + The background color of text of the standard output */ __stdBackgroundColor = ConsoleColor.NONE() /* - + A line that fill the width of an average console windows, simply an '=' character 151 long */ consoleLine = __copy("=",151)+crlf +/* + The console module in a printable string **simple.utilities.Console** +*/ +__CONSOLE_MODULE = "simple.utilities.Console" + +/* + Exception message to indicate that the parameter can only be a list of an instance of the @Class List class +*/ +__CONSOLE_LIST_ONLY = "Parameter can only be a list or an instance of the class List" + /* */ @@ -133,6 +139,9 @@ block printinLine(std_output,content) block printLine(std_output,fg,bg) std_output.printLine(fg,bg) +block flush_console(std_output) + std_output.flush() + /* Format the literal value to be printed in the output into the standard C Format with escape sequences. simple-lang @@ -240,19 +249,33 @@ private __stdBackgroundColor = ConsoleColor.NONE() block println(val) - val = formatEscapeSequence(val) + val = getObjectString(val) __print(std_output,val+nl) block print(val) - val = formatEscapeSequence(val) + val = getObjectString(val) __print(std_output,val) block vprintf(arg) - val = _vformatf(arg) + val = "" + if isList(arg) { + val = _vformatf(arg) + else + try { + obj = arg.object() + if !isString(obj) and isList(obj) { + val = _vformatf(obj) + else + throwWithTitle(__CONSOLE_MODULE,__CONSOLE_LIST_ONLY) + } + catch + throwWithTitle(__CONSOLE_MODULE,__CONSOLE_LIST_ONLY) + } + } __print(std_output,val) block printfc(color,val) - val = formatEscapeSequence(val) + val = getObjectString(val) __printwfb(std_output, color, this.__stdBackgroundColor, val) block printLine(fg,bg) @@ -265,6 +288,34 @@ private block getStd() return std_output + + block flush() + __flush_console(std_output) + + private + + block getObjectString(val) + if isNull(val) { + val = "(null)" + elif isString(val) + val = formatEscapeSequence(val) + elif isNumber(val) + val = formatEscapeSequence(""+val) + elif isList(val) + _val = new List(val) + val = _val.toString() + elif isObject(val) + try { + val = val.toString() + catch + val = parseObjString(val) + } + } + return val + + block parseObjString(obj) + #to use ref meta to get obj and attr + return "(cannot print object)"#obj #undone diff --git a/simple/includes/simple_codegen.h b/simple/includes/simple_codegen.h index 3c2e7cb9..86953ba9 100644 --- a/simple/includes/simple_codegen.h +++ b/simple/includes/simple_codegen.h @@ -30,6 +30,7 @@ typedef enum IC_OPERATIONS { ICO_NEWOBJ , ICO_GIVE , ICO_PRIVATE , + ICO_FINAL , ICO_NEWLABEL , /* Control Structure */ ICO_JUMP , diff --git a/simple/includes/simple_item.h b/simple/includes/simple_item.h index 6794acbe..ac5c6dd7 100644 --- a/simple/includes/simple_item.h +++ b/simple/includes/simple_item.h @@ -26,6 +26,10 @@ typedef struct Item { ** Used when putting the item in the stack to refer to list or listitem */ unsigned int nObjectType:2 ; + + int isFinal ; + int initDec ; + /* Data */ union { struct String *string ; @@ -45,9 +49,10 @@ typedef struct Item { #define ITEMTYPE_POINTER 3 #define ITEMTYPE_LIST 4 #define ITEMTYPE_BLOCKPOINTER 5 +#define ITEMTYPE_FINAL 6 #define ITEM_NUMBERFLAG_NOTHING 0 #define ITEM_NUMBERFLAG_INT 1 -#define ITEM_NUMBERFLAG_DOUBLE 2 +#define ITEM_NUMBERFLAG_DOUBLE 2 /* Blocks */ SIMPLE_API Item * simple_item_new_gc ( void *pState,int ItemType ) ; @@ -139,6 +144,10 @@ SIMPLE_API void simple_item_setstring ( Item *pItem,const char *cStr ) ; SIMPLE_API void simple_item_setdouble ( Item *pItem,double x ) ; +SIMPLE_API void simple_item_setfinal(Item *pItem,double x ); + +SIMPLE_API void simple_item_setinitdec (Item *pItem,double x ); + SIMPLE_API void simple_item_setpointer ( Item *pItem,void *pValue ) ; SIMPLE_API void simple_item_setint ( Item *pItem,int x ) ; diff --git a/simple/includes/simple_list.h b/simple/includes/simple_list.h index 64910267..533eda8c 100644 --- a/simple/includes/simple_list.h +++ b/simple/includes/simple_list.h @@ -47,6 +47,7 @@ SIMPLE_API void simple_list_deleteitem_gc ( void *pState,List *list,int index ) SIMPLE_API void simple_list_print ( List *list ) ; SIMPLE_API int simple_list_gettype ( List *list, int index ) ; + /* int */ SIMPLE_API void simple_list_setint_gc ( void *pState,List *list, int index ,int number ) ; @@ -174,6 +175,8 @@ SIMPLE_API int simple_list_deliteminsidelist ( List *list,Item *pItem ) ; #define simple_list_getblockpointer(list,index) ( simple_list_getitem(list,index)->data.pBlock ) #define simple_list_callblockpointer(list,index,x) ( simple_list_getitem(list,index)->data.pBlock(x) ) #define simple_list_getdouble(list,index) simple_list_getitem(list,index)->data.dNumber +#define simple_list_getfinal(list,index) simple_list_getitem(list,index)->isFinal +#define simple_list_getinitdec(list,index) simple_list_getitem(list,index)->initDec #define simple_list_getstring(list,index) ( simple_string_get(simple_item_getstring(simple_list_getitem(list,index))) ) #define simple_list_getstringobject(list,index) ( simple_item_getstring(simple_list_getitem(list,index)) ) #define simple_list_getstringsize(list,index) ( simple_string_size(simple_item_getstring(simple_list_getitem(list,index))) ) diff --git a/simple/includes/simple_scanner.h b/simple/includes/simple_scanner.h index 06e527b8..9889f893 100644 --- a/simple/includes/simple_scanner.h +++ b/simple/includes/simple_scanner.h @@ -77,6 +77,7 @@ typedef enum SCANNER_KEYWORD { /* Packages */ KEYWORD_MODULE , KEYWORD_PRIVATE , + KEYWORD_FINAL , KEYWORD_STEP , KEYWORD_DO , KEYWORD_EXEC , diff --git a/simple/includes/simple_vm.h b/simple/includes/simple_vm.h index 13a6d460..099a31a5 100644 --- a/simple/includes/simple_vm.h +++ b/simple/includes/simple_vm.h @@ -70,6 +70,7 @@ typedef struct VM { char nInClassRegion ; List *aActiveModules ; char nPrivateFlag ; + char finalFlag ; char nGetSetProperty ; void *pGetSetObject ; char nGetSetObjType ; @@ -639,7 +640,7 @@ List * simple_vm_getglobalscope ( VM *vm ) ; #define SIMPLE_BLOCKMAP_NAME 1 #define SIMPLE_BLOCKMAP_PC 2 #define SIMPLE_BLOCKMAP_FILENAME 3 -#define SIMPLE_BLOCKMAP_PRIVATEFLAG 4 +#define SIMPLE_BLOCKMAP_PRIVATEFLAG 4 //multiblocklead /* BlockMap List Size */ #define SIMPLE_BLOCKMAP_NORMALSIZE 4 /* Variable Scope */ @@ -648,6 +649,7 @@ List * simple_vm_getglobalscope ( VM *vm ) ; #define SIMPLE_VARSCOPE_OBJSTATE 2 #define SIMPLE_VARSCOPE_GLOBAL 3 #define SIMPLE_VARSCOPE_NEWOBJSTATE 4 +#define SIMPLE_VARSCOPE_FINAL 5 /* ** OOP ** pClassesMap @@ -752,6 +754,7 @@ List * simple_vm_getglobalscope ( VM *vm ) ; #define SIMPLE_VM_ERROR_BADCOMMAND "RUNTIME ERROR 24 : Sorry, The command is not supported in this context" #define SIMPLE_VM_ERROR_LIBLOADERROR "RUNTIME ERROR 24 : Runtime Error Occur while loading the dynamic library!" #define SIMPLE_VM_ERROR_TEMPFILENAME "RUNTIME ERROR 24 : Error occurred while creating unique filename." +#define SIMPLE_VM_ERROR_CANNOT_ASSIGN_FINAL "RUNTIME ERROR 24 : Cannot assign a value to the final variable " /* Extra Size (for codeExecution) */ #define SIMPLE_VM_EXTRASIZE 2 /* Variables Location */ diff --git a/simple/sources/simple_item.c b/simple/sources/simple_item.c index c02481f9..7b9cb0dd 100644 --- a/simple/sources/simple_item.c +++ b/simple/sources/simple_item.c @@ -25,6 +25,10 @@ SIMPLE_API Item * simple_item_new_gc ( void *pState,int ItemType ) printf( SIMPLE_OOM ) ; exit(0); } + /* Set the final flag to false */ + pItem->isFinal = 0 ; + /* Set the initial declaration to true */ + pItem->initDec = 1 ; /* Set Type */ pItem->nType = ITEMTYPE_NOTHING ; /* Delete pointer information */ @@ -53,6 +57,10 @@ SIMPLE_API void simple_item_print ( Item *pItem ) assert(pItem != NULL); ItemType = pItem->nType ; switch ( ItemType ) { + case ITEMTYPE_FINAL : + /* Work */ + printf( "%i \n",pItem->isFinal ) ; + break; case ITEMTYPE_NOTHING : /* Work */ break ; @@ -66,7 +74,7 @@ SIMPLE_API void simple_item_print ( Item *pItem ) printf( "%d\n ",pItem->data.iNumber ) ; } else { printf( "%f \n",pItem->data.dNumber ) ; - } + } //int break ; case ITEMTYPE_POINTER : /* Work */ @@ -100,6 +108,8 @@ SIMPLE_API void simple_item_content_delete_gc ( void *pState,Item *pItem ) /* Delete number information */ pItem->data.dNumber = 0 ; pItem->data.iNumber = 0 ; + pItem->isFinal = 0 ; + pItem->initDec = 1 ; pItem->NumberFlag = ITEM_NUMBERFLAG_NOTHING ; } @@ -108,6 +118,8 @@ SIMPLE_API void simple_item_settype_gc ( void *pState,Item *pItem,int ItemType ) assert(pItem != NULL); /* When we set the type we remove the current content at first */ simple_item_content_delete_gc(pState,pItem); + pItem->isFinal = 0 ; + pItem->initDec = 0 ; switch ( ItemType ) { case ITEMTYPE_NOTHING : pItem->nType = ITEMTYPE_NOTHING ; @@ -171,6 +183,8 @@ SIMPLE_API void simple_itemarray_setdouble_gc ( void *pState,Item list[], int in #define simple_list_getstring(list,index) ( simple_string_get(simple_item_getstring(simple_list_getitem(list,index))) ) #define simple_list_getstringobject(list,index) ( simple_item_getstring(simple_list_getitem(list,index)) ) #define simple_list_getstringsize(list,index) ( simple_string_size(simple_item_getstring(simple_list_getitem(list,index))) ) +#define simple_list_getfinal(list,index) simple_list_getitem(list,index)->isFinal +#define simple_list_getinitdec(list,index) simple_list_getitem(list,index)->initDec /* String */ SIMPLE_API void simple_itemarray_setstsimple_gc ( void *pState,Item list[], int index ,const char *str ) @@ -205,6 +219,16 @@ SIMPLE_API void simple_item_setdouble_gc ( void *pState,Item *pItem,double x ) pItem->NumberFlag = ITEM_NUMBERFLAG_DOUBLE ; } +SIMPLE_API void simple_item_setfinal_gc ( void *pState,Item *pItem,double x ) +{ + pItem->isFinal = x ; +} + +SIMPLE_API void simple_item_setinitdec_gc ( void *pState,Item *pItem,double x ) +{ + pItem->initDec = x ; +} + SIMPLE_API void simple_item_setpointer_gc ( void *pState,Item *pItem,void *pValue ) { simple_item_settype_gc(pState,pItem,ITEMTYPE_POINTER); @@ -283,6 +307,16 @@ SIMPLE_API void simple_item_setdouble ( Item *pItem,double x ) simple_item_setdouble_gc(NULL,pItem,x); } +SIMPLE_API void simple_item_setfinal( Item *pItem,double x ) +{ + simple_item_setfinal_gc(NULL,pItem,x); +} + +SIMPLE_API void simple_item_setinitdec( Item *pItem,double x ) +{ + simple_item_setinitdec_gc(NULL,pItem,x); +} + SIMPLE_API void simple_item_setpointer ( Item *pItem,void *pValue ) { simple_item_setpointer_gc(NULL,pItem,pValue); diff --git a/simple/sources/simple_list.c b/simple/sources/simple_list.c index e3d1b653..d766e75c 100644 --- a/simple/sources/simple_list.c +++ b/simple/sources/simple_list.c @@ -430,6 +430,7 @@ SIMPLE_API void simple_list_adddouble_gc ( void *pState,List *list,double x ) simple_list_newitem_gc(pState,list); simple_list_setdouble_gc(pState,list,simple_list_getsize(list),x); } + /* String */ SIMPLE_API void simple_list_setstsimple_gc ( void *pState,List *list, int index ,const char *str ) diff --git a/simple/sources/simple_scanner.c b/simple/sources/simple_scanner.c index 299720af..d30aa6f8 100644 --- a/simple/sources/simple_scanner.c +++ b/simple/sources/simple_scanner.c @@ -22,7 +22,7 @@ const char * SIMPLE_KEYWORDS[] = {"if","to","or","and","not","for","new","block" "read","__exit__","break","try","catch","finally","switch","default", -"in","continue","module","private","step","do","exec","elif", +"in","continue","module","private","final","step","do","exec","elif", "get","case"/**, "changesimplekeyword","changesimpleoperator","loadsyntax"**/} ; /* Blocks */ @@ -574,6 +574,7 @@ void simple_scanner_keywords ( Scanner *scanner ) /* Modules */ simple_list_addstring_gc(scanner->sState,scanner->Keywords,"module"); simple_list_addstring_gc(scanner->sState,scanner->Keywords,"private"); + simple_list_addstring_gc(scanner->sState,scanner->Keywords,"final"); simple_list_addstring_gc(scanner->sState,scanner->Keywords,"step"); simple_list_addstring_gc(scanner->sState,scanner->Keywords,"do"); simple_list_addstring_gc(scanner->sState,scanner->Keywords,"exec"); diff --git a/simple/sources/simple_stmt.c b/simple/sources/simple_stmt.c index e970d194..b56c5016 100644 --- a/simple/sources/simple_stmt.c +++ b/simple/sources/simple_stmt.c @@ -237,6 +237,20 @@ int simple_parser_class ( Parser *parser ) return 0 ; } } + + /* Statement --> final */ + if ( simple_parser_iskeyword(parser,KEYWORD_FINAL) ) { + simple_parser_nexttoken(parser); + /* Generate Code */ + /* Change Label After Class to BlockFlag to Jump to Final */ + simple_parser_icg_newoperation(parser,ICO_FINAL); + #if SIMPLE_PARSERTRACE + SIMPLE_STATE_CHECKPRINTRULES + + puts("Rule : Statement --> 'Final'"); + #endif + return 1 ; + } return simple_parser_stmt(parser) ; } diff --git a/simple/sources/simple_vm.c b/simple/sources/simple_vm.c index 2318810e..ebb0aba4 100644 --- a/simple/sources/simple_vm.c +++ b/simple/sources/simple_vm.c @@ -396,6 +396,9 @@ void simple_vm_execute ( VM *vm ) case ICO_ASSIGNMENT : simple_vm_assignment(vm); break ; + case ICO_FINAL : + vm->finalFlag = 1 ; + break ; case ICO_INC : simple_vm_inc(vm); break ; @@ -1299,13 +1302,10 @@ void simple_vm_addglobalvariables ( VM *vm ) simple_vm_addnewstringvar(vm,"__err__","NULL"); simple_vm_addnewpointervar(vm,"simple_settemp_var",NULL,0); simple_vm_addnewnumbervar(vm,"simple_tempflag_var",0); - simple_vm_addnewcpointervar(vm,"stdin",stdin,"file"); - simple_vm_addnewcpointervar(vm,"stdout",stdout,"file"); - simple_vm_addnewcpointervar(vm,"stderr",stderr,"file"); - simple_vm_addnewpointervar(vm,"this",NULL,0); simple_vm_addnewstringvar(vm,"tab","\t"); simple_vm_addnewstringvar(vm,"cr","\r"); simple_vm_addnewstringvar(vm,"nl","\n"); + simple_vm_addnewpointervar(vm,"this",NULL,0); /* Add Command Line Parameters */ list = simple_vm_newvar2(vm,"cmdparams",vm->pActiveMem); simple_list_setint_gc(vm->sState,list,SIMPLE_VAR_TYPE,SIMPLE_VM_LIST); diff --git a/simple/sources/simple_vmstackvars.c b/simple/sources/simple_vmstackvars.c index 424ef499..391a8a3e 100644 --- a/simple/sources/simple_vmstackvars.c +++ b/simple/sources/simple_vmstackvars.c @@ -519,8 +519,9 @@ void simple_vm_minusminus ( VM *vm ) void simple_vm_assignmentpointer ( VM *vm ) { List *list, *list2 ; - Item *pItem ; - int x ; + Item *pItem ; + const char* var ; + int x , isFinal, initDec ; if ( vm->nNOAssignment == 0 ) { vm->pAssignment = SIMPLE_VM_STACK_READP ; /* Check trying to change the self pointer */ @@ -529,6 +530,15 @@ void simple_vm_assignmentpointer ( VM *vm ) if ( simple_list_islist((List *) vm->pAssignment,SIMPLE_VAR_VALUE) ) { list = simple_list_getlist((List *) vm->pAssignment,SIMPLE_VAR_VALUE) ; } + var = simple_list_getstring(((List *)vm->pAssignment),SIMPLE_VAR_NAME); + isFinal = simple_list_getfinal(((List *)vm->pAssignment),SIMPLE_VAR_NAME); + initDec = simple_list_getinitdec(((List *)vm->pAssignment),SIMPLE_VAR_NAME); + + if (isFinal == 1 && initDec == 0) { + simple_vm_error2(vm,SIMPLE_VM_ERROR_CANNOT_ASSIGN_FINAL,var); + } else if (isFinal == 1) { + simple_item_setinitdec(simple_list_getitem(((List *)vm->pAssignment),SIMPLE_VAR_NAME),0); + } } else if ( SIMPLE_VM_STACK_OBJTYPE == SIMPLE_OBJTYPE_LISTITEM ) { pItem = (Item *) vm->pAssignment ; diff --git a/simple/sources/simple_vmvars.c b/simple/sources/simple_vmvars.c index c5daa00a..559ac534 100644 --- a/simple/sources/simple_vmvars.c +++ b/simple/sources/simple_vmvars.c @@ -219,6 +219,7 @@ void simple_vm_newvar ( VM *vm,const char *cStr ) assert(vm->pActiveMem); list = simple_vm_newvar2(vm,cStr,vm->pActiveMem); vm->nsp++ ; + SIMPLE_VM_STACK_SETPVALUE(list); SIMPLE_VM_STACK_OBJTYPE = SIMPLE_OBJTYPE_VARIABLE ; /* Set the scope of the new variable */ @@ -230,6 +231,13 @@ void simple_vm_newvar ( VM *vm,const char *cStr ) } else { vm->nVarScope = SIMPLE_VARSCOPE_NOTHING ; } + /* Initial Declaration */ + simple_item_setinitdec(simple_list_getitem(list,SIMPLE_VAR_NAME),1); + /* Final Flag */ + if (vm->finalFlag == 1) { + simple_item_setfinal(simple_list_getitem(list,SIMPLE_VAR_NAME),1); + vm->finalFlag = 0; + } /* Add Scope to aLoadAddressScope */ simple_list_addint_gc(vm->sState,vm->aLoadAddressScope,vm->nVarScope); } @@ -250,6 +258,7 @@ List * simple_vm_newvar2 ( VM *vm,const char *cStr,List *pParent ) if ( pParent->pHashTable == NULL ) { pParent->pHashTable = simple_hashtable_new(); } + simple_hashtable_newpointer(pParent->pHashTable,cStr,list); return list ; }