-
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