-
Notifications
You must be signed in to change notification settings - Fork 0
kiransj/m-programming-language
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
This code is simple programming lanuage named M. This programming language supports objects, conditional statements, dynamic structures, arrays, loops, variable declaration, functions, recursion and support to call ‘C’ function from M. The objective of this projects is to have a compiler and runtime in less than 100KB so it could be embedded into other projects. Once embedded this language can be used to take decision on behalf of the program. The feature of the lanuage are 1. variable := Variable are declared using 'var' keyword. Every variable used should be declared 2. conditions stmts := if() stmt endif, if() stmt else stmt endif, if() stmt elif() stmt elif() stmt else endif. supported 3. loops. := while(expr) ... endwhile is supported 5. Calling C functions from M. := Completed 6. functions. := Completed. Recursive functions are supported. Passing arguments to functions are also supported 7. global variables. := In progress. 8. Objects. := Done. 9. Structure := Dynamic structure done. (where elements can be added dynamically to the structure) Local variables are defined as and when they are encountered. (this will change soon). Syntax of M language. A factorial program ==========Sample program to show loops and conditional statments ================== function Main() var a := 1; while(a < 6) if(a < 2) output("a<2"); elif(a > 2) output("a>2"); if(a > 5) output("a>5"); elif(a < 5) output("a<5)"); else output("a==5"); endif elif(a == 2) output("a==2"); endif a := a + 1; endwhile endfunction =========End of program================== How to use objects ===== Start of a program ========= function GetKeyValue() var v; v :=KeyValue(); if(typeof(v) == "keyvalue") KeyValueAdd(v, "version", "10"); KeyValueAdd(v, "Path", "/home/kiran/root/bin"); KeyValueAdd(v, "time", "10:30"); return v; endif output("KeyValue() failed"); return (0); endfunction function Main() var v, a; v := GetKeyValue(); if(typeof(v) != "keyvalue") output("KeyValue() failed"); return (0); endif if(KeyValueIterator(v)) while(typeof(a:=KeyValueNext(v)) == "struct") output(a->key + " = " + a->value); endwhile endif return (1); endfunction ========= end object program ============ =========== File List program in M ===================== function Main() var obj, tmp; obj := FileListObject("/home/kiransj/"); if(typeof(obj) != "filelist") output("FileListObject() failed"); else output("FileListObject() succeed"); while(typeof(tmp := FileListGet(obj)) == "struct") if(!tmp->isdir && !tmp->executable) output(tmp->name + " " ); endif endwhile endif return 0; endfunction ======================================================== This source code for M has the following parts. 1. Compiler we use the lemon parser to generate the C code from context free grammer. This parser generates the byte code from the program. The byte code generated is of register architecture insted of stack architecture. What's register architecture. Consider this statment a*(b+c) the above statment can be solved in two ways. the stack architecture PUSH A PUSH B PUSH C ADD => adds B & C and pushes the result back to stack MUL => MUL A and (B&C value pushed into stack) and push the result back. In the register architecture the same expression becomes ADD B, C, %1 => add B and C and copy it to register 1 MUL A, %1, %2 => add A and register 1 and copy the result to register 2 To See the generated bytecode Uncomment the macro in compiler.c file. The grammer is written for the lemon parsers. (http://www.hwaci.com/sw/lemon/) Lemon parser is used in sqlite. The grammer understands the M lanuage syntax and generates the byteCode.The grammer is in the file grammer.y The compiler files are grammer.y, executable.c, functions.c 2. Tokenzier This is written in flex and c. This program reads a file and then generates a set of tokens from the file. Examaple a:=10*width; the program generates the following tokens variable a operator := Numebr 10 variable width These are then passed to grammer to check if this syntax is correct and then byte code are generated from the output of grammer. See files lexel.l, tokenizer.c files for the tokenizers. 3. Interpreters This interprets the byte code generated by the compiler. The interpreter uses a set of stacks, linked list to execute the byte code. The files are execute_context.c The memory leaks are monitered using valgrind. Till now there is no memory leaks in the code.
About
A sample implementation of a programming language with supports for functions, variables and loops.
Resources
Stars
Watchers
Forks
Packages 0
No packages published