Commits

Pierre Surply  committed f1156df Merge

merge

  • Participants
  • Parent commits d845213, c1b93df

Comments (0)

Files changed (92)

 ### Classes
 
     # point.mr
+    
+    begin class
+      integer x
+      integer y
 
-    integer x
-    integer y
-
-    func init(nx, ny)
+      func init(nx, ny)
             self.x <- nx
 	        self.y <- ny
 	        return self
-    end
+      end
 
-    func squared_dist()
+      func squared_dist()
             return (self.x * self.x) + \
                    (self.y * self.y)
+      end
     end
     
     # main.mr

File compiler/_tags

+true: use_menhir

File compiler/backend/gen.ml

 **    along with Mara.  If not, see <http://www.gnu.org/licenses/>.
 **
 ** Started on  Thu Dec 27 19:13:52 2012 Pierre Surply
-** Last update Tue Feb 12 09:11:05 2013 Pierre Surply
+** Last update Fri Mar 22 18:19:48 2013 Pierre Surply
 *)
 
 open Ast
 		      Instr ("add", RegReg(25, 0));
 		      Instr ("clr", Reg(1))]
 	    | "/" -> [Instr ("movw", RegReg(22, 18));
-		      Instr ("rcall", String "__divmodhi4");
+		      Instr ("call", String "__divmodhi4");
 		      Instr ("movw", RegReg(24, 22))]
 	    | "%" -> [Instr ("movw", RegReg(22, 18));
-		      Instr ("rcall", String "__divmodhi4")]
+		      Instr ("call", String "__divmodhi4")]
 	    | "|" -> [Instr ("or", RegReg(24, 18));
 		      Instr ("or", RegReg(25, 19))]
 	    | "&" -> [Instr ("and", RegReg(24, 18));
 	end
   | Fcall (id, el, _) ->
     List.concat
-      [(List.concat
+      [[Instr ("push", Reg(28));
+        Instr ("push", Reg(29))];
+       (List.concat
           (List.map
 	     (fun x ->
 	       p_expr mem x@
 	         [Instr ("push", Reg(25));
 	          Instr ("push", Reg(24))])
 	     el));
-       [Instr ("rcall",
+       [Instr ("call",
 	       String id)];
        (List.concat
 	  (List.map
 	       [Instr ("pop", Reg(0));
 	        Instr ("pop", Reg(0))])
 	     el));
-       [Instr ("in", RegString (28, "__SP_L__"));
-        Instr ("in", RegString (29, "__SP_H__"));
-       ]]
+       [Instr ("pop", Reg 29);
+        Instr ("pop", Reg 28)]]
   | Mcall (e, m, el, ty, loc) ->
     let ty = !ty in
     p_expr mem (Fcall (ty ^ "_" ^ m, e::el, loc))
     let size = (Hashtbl.find cl_mem cl).Mem.size in
     [Instr ("ldi", RegInt(24, size));
      Instr ("ldi", RegInt(25, 0));
-     Instr ("rcall", String("malloc"));
+     Instr ("call", String("malloc"));
      Instr ("push", Reg(25));
      Instr ("push", Reg(24))]@
       (List.concat
 		 [Instr ("push", Reg(25));
 		    Instr ("push", Reg(24))])
 	    el))@
-	[Instr ("rcall", String(cl ^ "_init"))]@
+	[Instr ("call", String(cl ^ "_init"))]@
       (List.concat
 	 (List.map
 	    (fun _ ->
        | Some s ->
          p_expr mem
            (Mcall (e, "destr", [], ref s, loc)));
-       [Instr ("rcall", String("free"))]]
+       [Instr ("call", String("free"))]]
 
 and p_body mem b =
   List.concat (List.map (p_instr mem) b)
 	(fun s _ -> 
 	  if not(List.mem s al) then
 	    Mem.add mem s) ty in
-      Mem.add mem "~rcall";
+      Mem.add mem "~call";
       let _ = List.iter
 	(Mem.add mem) (List.rev al) in
       if not (!dstatic) then

File compiler/conf.ml

 **    along with Mara.  If not, see <http://www.gnu.org/licenses/>.
 **
 ** Started on  Tue Dec 25 17:11:59 2012 Pierre Surply
-** Last update Fri Mar 15 18:45:39 2013 Pierre Surply
+** Last update Tue Mar 26 08:56:48 2013 Pierre Surply
 *)
 
 type t =
 
 let conf =
   {
-    version = 5;
+    version = 8;
     mmcu = "atmega8";
     cur_file = "";
     files = Queue.create ();

File compiler/main.ml

 **    along with Mara.  If not, see <http://www.gnu.org/licenses/>.
 **
 ** Started on  Fri Nov  9 15:58:29 2012 Pierre Surply
-** Last update Fri Mar 15 18:40:31 2013 Pierre Surply
+** Last update Fri Mar 22 18:01:26 2013 Pierre Surply
 *)
 
 open Conf
   gen_asm ast dst;
   if build_hex f dst then
     show_time ()
+  else
+    exit 1
 
 let main () =
   arg ();

File compiler/parser/lexer.mll

 **    along with Mara.  If not, see <http://www.gnu.org/licenses/>.
 **
 ** Started on  Fri Nov  9 15:58:41 2012 Pierre Surply
-** Last update Fri Mar 15 15:13:29 2013 Pierre Surply
+** Last update Sat Mar 16 22:36:26 2013 Pierre Surply
 *)
 
 {
      ("]",	RBRACKET);
      ("or",	OR);
      ("and",	AND);
+     ("bitls",	LSB);
      ("<<",	LSB);
      ("<<<<",	DLSB);
+     ("bitrs",	RSB);
      (">>",	RSB);
      (">>>>",	DRSB);
+     ("bitor",	LOR);
      ("|",	LOR);
      ("||",	DLOR);
+     ("bitand",	LAND);
      ("&",	LAND);
      ("&&",	DLAND);
      ("<-",	EQ);
      (";",	SCOLON);
      ("?",	QUEST);
      ("not",	NOT);
+     ("compl",	TILDE);
      ("~",	TILDE);
      ("->",	TRANS);
     ]
 let int1 = "true"
 
 let symba = "+" | "++" | "-" | "--" | "*" | "**" | "/" | "//" | "%" | "%" | "(" | ")" | "{" | "}" | 
-    "<<" | "<<<<" | ">>" | ">>>>" | "|" | "||" | "&" | "&&" | "or" | "and" | "<-" | "->" | "," |
+    "<<" | "bitls" | "<<<<" | ">>" | "bitrs" | ">>>>" | "|" | "bitor" | "||" | "&" | "bitand" | "&&" | "or" | "and" | "<-" | "->" | "," |
 	"<" | ">" | "<=" | ">=" | "<>" | "=" | "[" | "]" | "." | ":" |
-	    "not" | "~" | "_" | "?" | "::" | ";"
+	    "not" | "~" | "compl" | "_" | "?" | "::" | ";"
 
 let integer = ['0'-'9']+ | ("0b" ['0' '1']+) | ("0x" ['0'-'9' 'A'-'F' 'a'-'f']+)
 

File compiler/parser/parser.mly

 **    along with Mara.  If not, see <http://www.gnu.org/licenses/>.
 **
 ** Started on  Fri Nov  9 15:58:54 2012 Pierre Surply
-** Last update Fri Mar 15 15:13:37 2013 Pierre Surply
+** Last update Mon Mar 18 08:18:31 2013 Pierre Surply
 *)
 
   open Parsing
   open Lexing
 
-  let make_pos () = (symbol_start_pos (), symbol_end_pos ())
-
-  let print_error () =
-    Error.print_error (make_pos ());
+  let print_error pos =
+    Error.print_error pos;
     Printf.fprintf stderr "** Syntax error\n";
     exit 2
-
-  let compound lexpr expr op =
-    Ast.Affect(lexpr,
-	       Ast.BinOp(op, lexpr,
-			 expr,
-			 make_pos ()),
-	       make_pos ()) 
 %}
 
 %token <int> INT
 %%
 
 main:
-  | header setup loop endf 	{ Ast.Loop ($1, $2, $3) }
-  | header classb endf		{ Ast.Class ($1, $2) }
-  | header fsm endf		{ Ast.FSM ($1, $2) }
+  | h=header s=setup EOL+ l=loop endf           { Ast.Loop (h, s, l) }
+  | h=header c=classb endf                      { Ast.Class (h, c) }
+  | h=header f=fsm endf                         { Ast.FSM (h, f) }
+;
+
+llist(X):
+  | EOL* x=X endl l=llist(X)                    { x::l }
+  | EOL*                                        { [] }        
+;
+
+%inline endl:
+  | EOL                                         {}
+  | EOF                                         {}
+;
+
+%inline endf:
+  | EOL* EOF                                    {}
 ;
 
-endf:
-  | EOL endf	{}
-  | EOF		{}
+%inline classb:
+  | BEGIN CLASS EOL cd=classbody END            { cd }
+  | BEGIN LIB EOL cd=classbody END              { Ast.Static::cd }
 ;
 
-classb:
-  | BEGIN CLASS EOL classdef END { $4 }
-  | BEGIN LIB EOL classdef END   { Ast.Static::$4 }
+%inline classbody:
+  | cl=llist(classdef)                          { cl }
 ;
 
 classdef:
-  | STATIC EOL classdef                 { Ast.Static::$3 }
-  | FUN ID LPAREN varlist RPAREN EOL body END classdef
-      { Ast.Fdef($2, $4, $7)::$9 }
-  | ID ID EOL classdef			{ Ast.Vdef($1, $2)::$4}
-  | EOL classdef			{ $2 }
-  | 					{ [] }
-  | error				{ print_error ()}
+  | STATIC                                      { Ast.Static }
+  | FUN id=ID LPAREN vl=varlist RPAREN EOL b=body END
+                                                { Ast.Fdef(id, vl, b)}
+  | ty=ID id=ID                                 { Ast.Vdef(ty, id) }
+  | error                                       { print_error ($startpos, $endpos) }
+;
+
+%inline header:
+  | h=llist(headerdef)                          { h }
 ;
 
-header:
-  | USING ID EOL header    { Ast.Using ($2, make_pos ())::$4 }
-  | EOL header	           { $2 }
-  | 	                   { [] }
+headerdef:
+  | USING id=ID                                 { Ast.Using (id, ($startpos, $endpos)) }
 ;
 
-setup:
-  | BEGIN SETUP EOL body END	{ $4 }
+%inline setup:
+  | BEGIN SETUP EOL b=body END                  { b }
 ;
 
-loop:
-  | BEGIN LOOP EOL body	END	{ $4 }
-  | EOL loop			{ $2 }
+%inline loop:
+  | BEGIN LOOP EOL b=body END                   { b }
 ;
 
-body:
-  | instr EOL body	{ $1::$3 }
-  | EOL	body		{ $2 }
-  |			{ [] }
+%inline body:
+  | b=llist(instr)                              { b }
 ;
 
 instr:
-  | lexpr EQ expr				{ Ast.Affect($1,$3, make_pos ()) }
-  | compound                                    { $1 }
-  | VAR ID EQ expr				{ Ast.Let($2, $4, make_pos ()) }
-  | RETURN expr					{ Ast.Return ($2, make_pos ()) }
-  | IF expr THEN body elif			{ Ast.IfElse ($2, $4, $5, make_pos ()) }
-  | IF expr THEN body ENDIF			{ Ast.If ($2, $4, make_pos ()) }
-  | instr IF expr				{ Ast.If ($3, [$1], make_pos ()) }
-  | WHILE expr DO bodyopt DONE			{ Ast.While ($2, $4, make_pos ()) }
-  | FOR ID EQ expr TO expr DO bodyopt DONE	{ Ast.For (true, $2, $4, $6, $8, make_pos ()) }
-  | FOR ID EQ expr DOWNTO expr DO bodyopt DONE	{ Ast.For (false, $2, $4, $6, $8, make_pos ()) }
-  | expr DCOLON instr
-      { Ast.For
-	  (true,
-	   "__i",
-	   Ast.Int(1, make_pos ()),
-	   $1,
-	   [$3],
-	   make_pos ()) }
-  | WAITFOR expr				{ Ast.While ($2, [], make_pos ()) }
-  | DEL expr                                    { Ast.Del ($2, ref None, make_pos()) }
-  | expr					{ Ast.Expr($1, make_pos ()) }
-  | error					{ print_error () }
+  | le=lexpr EQ e=expr				{ Ast.Affect(le, e, ($startpos, $endpos)) }
+  | le=lexpr op=compound e=expr                 { Ast.Affect(le,
+	                                                     Ast.BinOp(op, le,
+			                                               e,
+			                                               ($startpos, $endpos)),
+	                                                     ($startpos, $endpos)) }
+  | VAR id=ID EQ e=expr				{ Ast.Let(id, e, ($startpos, $endpos)) }
+  | RETURN e=expr				{ Ast.Return (e, ($startpos, $endpos)) }
+  | IF c=expr THEN b=body ei=elif		{ Ast.IfElse (c, b, ei, ($startpos, $endpos)) }
+  | IF c=expr THEN b=body ENDIF			{ Ast.If (c, b, ($startpos, $endpos)) }
+  | i=instr IF c=expr				{ Ast.If (c, [i], ($startpos, $endpos)) }
+  | WHILE c=expr DO b=body DONE 		{ Ast.While (c, b, ($startpos, $endpos)) }
+  | FOR id=ID EQ i=expr TO c=expr DO b=body DONE
+                                                { Ast.For (true, id, i, c, b, ($startpos, $endpos)) }
+  | FOR id=ID EQ i=expr DOWNTO c=expr DO b=body DONE
+                                                { Ast.For (false, id, i, c, b, ($startpos, $endpos)) }
+  | c=expr DCOLON i=instr
+                                                { Ast.For
+	                                          (true,
+	                                           "__i",
+	                                           Ast.Int(1, ($startpos, $endpos)),
+	                                           c,
+	                                           [i],
+	                                           ($startpos, $endpos)) }
+  | WAITFOR c=expr				{ Ast.While (c, [], ($startpos, $endpos)) }
+  | DEL e=expr                                  { Ast.Del (e, ref None, ($startpos, $endpos)) }
+  | e=expr					{ Ast.Expr(e, ($startpos, $endpos)) }
+  | error					{ print_error ($startpos, $endpos) }
 ;
 
-compound:
-  | lexpr DADD expr     { compound $1 $3 "+"  }
-  | lexpr DMINUS expr   { compound $1 $3 "-"  }
-  | lexpr DTIMES expr   { compound $1 $3 "*"  }
-  | lexpr DDIV expr     { compound $1 $3 "/"  }
-  | lexpr DMOD expr     { compound $1 $3 "%"  }
-  | lexpr DLSB expr     { compound $1 $3 "<<" }
-  | lexpr DRSB expr     { compound $1 $3 ">>" }
-  | lexpr DLOR expr     { compound $1 $3 "|"  }
-  | lexpr DLAND expr    { compound $1 $3 "&"  }
+%inline compound:
+  | DADD                                        { "+"  }
+  | DMINUS                                      { "-"  }
+  | DTIMES                                      { "*"  }
+  | DDIV                                        { "/"  }
+  | DMOD                                        { "%"  }
+  | DLSB                                        { "<<" }
+  | DRSB                                        { ">>" }
+  | DLOR                                        { "|"  }
+  | DLAND                                       { "&"  }
 ;
 
 elif:
-  | ELSE body ENDIF			{ $2 }
-  | ELIF expr THEN body elif	{ [Ast.IfElse ($2, $4, $5, make_pos ())] }
-  | ELIF expr THEN body	ENDIF	{ [Ast.If ($2, $4, make_pos ())] }
+  | ELSE b=body ENDIF                           { b }
+  | ELIF c=expr THEN b=body ei=elif             { [Ast.IfElse (c, b, ei, ($startpos, $endpos))] }
+  | ELIF c=expr THEN b=body ENDIF       	{ [Ast.If (c, b, ($startpos, $endpos))] }
 ;
 
-bodyopt:
-  | EOL body		{ $2 }
-  | instr		{ [$1] }
-
 lexpr:
-  | expr DOT ID 			{ Ast.Field($1, $3, ref "", make_pos ()) }
-  | ID					{ Ast.Var($1, make_pos ()) }
+  | e=expr DOT i=ID                             { Ast.Field(e, i, ref "", ($startpos, $endpos)) }
+  | i=ID                                        { Ast.Var(i, ($startpos, $endpos)) }
 ;
 
-varlist:
-  | ID COMMA varlist	{ $1::$3 }
-  | ID			{ [$1] }
-  |			{ [] }
+%inline varlist:
+  | vl=separated_list(COMMA, ID)                { vl }
 ;
 
-exprlist:
-  | expr COMMA exprlist		{ $1::$3 }
-  | expr			{ [$1] }
-  |				{ [] }
+%inline exprlist:
+  | el=separated_list(COMMA, expr)              { el }
 ;
 
 declist:
-  | expr SCOLON declist
-      { Ast.New("list_node", [$1; $3], make_pos()) }
-  | expr                        
-      { Ast.New("list_node", [$1; Ast.ENone(make_pos ())], make_pos()) }
-  |                             { Ast.ENone(make_pos ()) }
+  | e=expr SCOLON dl=declist                    { Ast.New("list_node", [e; dl], ($startpos, $endpos)) }
+  | e=expr                                      { Ast.New("list_node",
+                                                          [e; Ast.ENone(($startpos, $endpos))],
+                                                          ($startpos, $endpos)) }
+  |                                             { Ast.ENone(($startpos, $endpos)) }
 ;
 
 expr:
-  | NONE                                { Ast.ENone(make_pos ()) }
-  | INT					{ Ast.Int($1, make_pos ()) }
-  | CHAR				{ Ast.Int(Char.code $1, make_pos ()) }
-  | STR					{ Ast.Str($1, make_pos ()) }
-  | LBRACE ID COLON expr RBRACE		{ Ast.Cast($2, $4, make_pos ()) }
-  | ID					{ Ast.Var($1, make_pos ()) }
-  | LPAREN expr RPAREN			{ $2 }
-  | expr ADD expr			{ Ast.BinOp("+", $1, $3, make_pos ()) }
-  | expr MINUS expr			{ Ast.BinOp("-", $1, $3, make_pos ()) }
-  | expr TIMES expr			{ Ast.BinOp("*", $1, $3, make_pos ()) }
-  | expr DIV expr			{ Ast.BinOp("/", $1, $3, make_pos ()) }
-  | expr MOD expr			{ Ast.BinOp("%", $1, $3, make_pos ()) }
-  | expr LSB expr			{ Ast.BinOp("<<", $1, $3, make_pos ()) }
-  | expr RSB expr			{ Ast.BinOp(">>", $1, $3, make_pos ()) }
-  | expr LOR expr			{ Ast.BinOp("|", $1, $3, make_pos ()) }
-  | expr LAND expr			{ Ast.BinOp("&", $1, $3, make_pos ()) }
-  | expr AND expr			{ Ast.BinOp("and", $1, $3, make_pos ()) }
-  | expr OR expr			{ Ast.BinOp("or", $1, $3, make_pos ()) }
-  | expr GT expr			{ Ast.BinOp(">", $1, $3, make_pos ()) }
-  | expr GE expr			{ Ast.BinOp(">=", $1, $3, make_pos ()) }
-  | expr LT expr			{ Ast.BinOp("<", $1, $3, make_pos ()) }
-  | expr LE expr			{ Ast.BinOp("<=", $1, $3, make_pos ()) }
-  | expr NEQ expr			{ Ast.BinOp("!=", $1, $3, make_pos ()) }
-  | expr DEQ expr			{ Ast.BinOp("==", $1, $3, make_pos ()) }
-  | MINUS expr %prec UMINUS		{ Ast.UniOp("-", $2, make_pos ()) }
-  | NOT expr				{ Ast.UniOp("not", $2, make_pos ()) }
-  | TILDE expr				{ Ast.UniOp("~", $2, make_pos ()) }
-  | expr QUEST expr COLON expr		{ Ast.Tern($1, $3, $5, make_pos ()) }
-  | NEW ID LPAREN exprlist RPAREN	{ Ast.New($2, $4, make_pos ()) }
-  | ASM STR				{ Ast.Asm(None, $2, make_pos ()) }
-  | ASM LBRACE expr RBRACE STR		{ Ast.Asm(Some $3, $5, make_pos ()) }
-  | expr DOT ID LPAREN exprlist RPAREN	{ Ast.Mcall($1, $3, $5, ref "", make_pos ()) }
-  | ID LPAREN exprlist RPAREN           { Ast.Fcall($1, $3, make_pos ()) }
-  | expr DOT ID 			{ Ast.Field($1, $3, ref "", make_pos ()) }
-  | LBRACKET declist RBRACKET           { Ast.New("list", [$2], make_pos ()) }
-  | expr LBRACKET expr RBRACKET 	{ Ast.Mcall($1, "get", [$3], ref "", make_pos ()) }
+  | NONE                                        { Ast.ENone(($startpos, $endpos)) }
+  | i=INT                                       { Ast.Int(i, ($startpos, $endpos)) }
+  | c=CHAR      				{ Ast.Int(Char.code c, ($startpos, $endpos)) }
+  | str=STR					{ Ast.Str(str, ($startpos, $endpos)) }
+  | LBRACE ty=ID COLON e=expr RBRACE		{ Ast.Cast(ty, e, ($startpos, $endpos)) }
+  | id=ID					{ Ast.Var(id, ($startpos, $endpos)) }
+  | LPAREN e=expr RPAREN			{ e }
+  | le=expr op=binop re=expr			{ Ast.BinOp(op, le, re, ($startpos, $endpos)) }
+  | MINUS e=expr %prec UMINUS                   { Ast.UniOp("-", e, ($startpos, $endpos)) }
+  | op=uniop e=expr                             { Ast.UniOp(op, e, ($startpos, $endpos)) }
+  | c=expr QUEST t=expr COLON f=expr		{ Ast.Tern(c, t, f, ($startpos, $endpos)) }
+  | NEW cl=ID LPAREN arg=exprlist RPAREN	{ Ast.New(cl, arg, ($startpos, $endpos)) }
+  | ASM code=STR				{ Ast.Asm(None, code, ($startpos, $endpos)) }
+  | ASM LBRACE e=expr RBRACE code=STR		{ Ast.Asm(Some e, code, ($startpos, $endpos)) }
+  | o=expr DOT m=ID LPAREN arg=exprlist RPAREN	{ Ast.Mcall(o, m, arg, ref "", ($startpos, $endpos)) }
+  | f=ID LPAREN arg=exprlist RPAREN             { Ast.Fcall(f, arg, ($startpos, $endpos)) }
+  | o=expr DOT f=ID                             { Ast.Field(o, f, ref "", ($startpos, $endpos)) }
+  | LBRACKET l=declist RBRACKET                 { Ast.New("list", [l], ($startpos, $endpos)) }
+  | o=expr LBRACKET e=expr RBRACKET             { Ast.Mcall(o, "get", [e], ref "", ($startpos, $endpos)) }
+;
+
+%inline binop:
+  | ADD                                         { "+"   }
+  | MINUS                                       { "-"   }
+  | TIMES                                       { "*"   }
+  | DIV                                         { "/"   }
+  | MOD                                         { "%"   }
+  | LSB                                         { "<<"  }
+  | RSB                                         { ">>"  }
+  | LOR                                         { "|"   }
+  | LAND                                        { "&"   }
+  | AND                                         { "and" }
+  | OR                                          { "or"  }
+  | GT                                          { ">"   }
+  | GE                                          { ">="  }
+  | LT                                          { "<"   }
+  | LE                                          { "<="  }
+  | NEQ                                         { "!="  }
+  | DEQ                                         { "=="  }
+;
+
+%inline uniop:
+  | NOT                                         { "not" }
+  | TILDE       				{ "~"   }
 ;
 
-fsm:
-  | BEGIN FSM EOL fsmdef END 	{ $4 }
-  | error			{ print_error () }
+%inline fsm:
+  | BEGIN FSM EOL fd=fsmbody END                { fd }
+  | error                                       { print_error ($startpos, $endpos) }
+;
+
+%inline fsmbody:
+  | f=llist(fsmdef)                             { f }
 ;
 
 fsmdef:
-  | ID ID EOL fsmdef				{ Ast.AVdef($1, $2)::$4}
-  | STATE ID EOL state END EOL fsmdef		{ Ast.AState($2, $4)::$7 }
-  | INPUT ID EQ expr EOL fsmdef			{ Ast.AInput($2, $4)::$6 }
-  | EOL fsmdef 					{ $2 }
-  | 						{ [] }
+  | ty=ID id=ID                                 { Ast.AVdef(ty, id) }
+  | STATE id=ID EOL s=statebody END             { Ast.AState(id, s) }
+  | INPUT id=ID EQ c=expr                       { Ast.AInput(id, c) }
+;
+
+%inline statebody:
+  | s=llist(statedef)                           { s }
 ;
 
-state:
-  | ACTION EOL body END EOL state	{ Ast.SAction($3)::$6 }
-  | ID TRANS ID EOL state		{ Ast.STrans(Some $1, $3, make_pos ())::$5 }
-  | TRANS ID EOL state			{ Ast.STrans(None, $2, make_pos ())::$4 }
-  | EOL state				{ $2 }
-  |					{ [] }
+statedef:
+  | ACTION EOL b=body END                       { Ast.SAction(b) }
+  | id=ID TRANS dest=ID                         { Ast.STrans(Some id, dest, ($startpos, $endpos)) }
+  | TRANS dest=ID                               { Ast.STrans(None, dest, ($startpos, $endpos)) }
 ;

File stdlib/cstring.mr

-##
-## cstring.mr for Mara
-##  
-## Copyright (C) 2013 Pierre Surply
-## <pierre.surply@gmail.com>
-##
-## This file is part of Mara.
-##
-##    Mara is free software: you can redistribute it and/or modify
-##    it under the terms of the GNU General Public License as published by
-##    the Free Software Foundation, either version 3 of the License, or
-##    (at your option) any later version.
-##
-##    Mara is distributed in the hope that it will be useful,
-##    but WITHOUT ANY WARRANTY; without even the implied warranty of
-##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-##    GNU General Public License for more details.
-##
-##    You should have received a copy of the GNU General Public License
-##    along with Mara.  If not, see <http://www.gnu.org/licenses/>.
-##
-
-begin lib
-  func str_get(s, i)
-        asm{{cstring : s}} "movw r30, r24"
-        asm{i}           "add  r30, r24
-                          adc  r31, r25"
-        return asm       "ld   r24, Z
-                          ldi  r25, 0"
-  end
-
-  func str_set(s, i, x)
-        asm{{cstring : s}} "movw r30, r24"
-        asm{i}             "add  r30, r24
-                            adc  r31, r25"
-        asm{x}             "st   Z, r24"
-  end
-end

File stdlib/eeprom.mr

+# EEPROM
+
+begin lib
+  func eeprom_write(addr, data)
+    waitfor (asm "in     r24, EECR
+                  clr    r25" bitand (1 bitls 1))
+    asm{addr}    "out    EEARH, r25
+                  out    EEARL, r24"
+    asm{data}    "out    EEDR, r24
+                  sbi    EECR, 2
+                  sbi    EECR, 1"
+  end
+
+  func eeprom_read(addr)
+    waitfor (asm "in     r24, EECR
+                  clr    r25" bitand (1 bitls 1))
+    asm{addr}    "out    EEARH, r25
+                  out    EEARL, r24
+                  sbi    EECR, EERE"
+    return asm   "in     r24, EEDR
+                  clr    r25"
+  end
+end

File stdlib/string.mr

-##
-## string.mr for Mara
-##  
-## Copyright (C) 2013 Pierre Surply
-## <pierre.surply@gmail.com>
-##
-## This file is part of Mara.
-##
-##    Mara is free software: you can redistribute it and/or modify
-##    it under the terms of the GNU General Public License as published by
-##    the Free Software Foundation, either version 3 of the License, or
-##    (at your option) any later version.
-##
-##    Mara is distributed in the hope that it will be useful,
-##    but WITHOUT ANY WARRANTY; without even the implied warranty of
-##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-##    GNU General Public License for more details.
-##
-##    You should have received a copy of the GNU General Public License
-##    along with Mara.  If not, see <http://www.gnu.org/licenses/>.
-##
-
-using cstring
-using list
-
-begin class
-  integer         size
-  cstring         s
-
-  func init(size)
-        self.size <- size
-        self.s <- asm<size> "rcall malloc"
-        str_set(self.s, 0, 0)
-        return self
-  end
-
-  func destr()
-        asm<self.s> "rcall free"
-        return self
-  end
-
-  func set(i, x)
-        str_set(self.s, i, x)
-  end
-
-  func get(i)
-        return str_get(self.s, i)
-  end
-
-  func write_from(s, n)
-        var i <- 0
-        var c <- str_get(s, i)
-        while c and (i + n) < (self.size - 1) do
-                c <- str_get(s, i)
-                str_set(self.s, i + n, c)
-                i++
-        done
-        str_set(self.s, i + n, 0)
-  end
-
-  func write(s)
-        self.write_from(s, 0)
-  end
-
-  func cat(s)
-        var i <- 0
-        while str_get(self.s, i) do
-                i++
-        done
-        self.write_from(s, i)
-  end
-
-  func append_char(c)
-        var i <- 0
-        while str_get(self.s, i) do
-                i++
-        done
-        str_set(self.s, i, c)
-        str_set(self.s, i + 1, 0)
-  end
-
-  func cmp(s)
-        var i <- 0
-        var cs <- str_get(self.s, 0)
-        var cd <- str_get(s, 0)
-        while cd and cs and cd = cs do
-                i++
-                cs <- str_get(self.s, i)
-                cd <- str_get(s, i)
-        done
-        return (cs - cd)
-  end
-end

File stdlib/uart.mr

-# UART
-
-using cstring
-
-begin class
-  integer rate
-
-  func init(rate)
-        self.rate <- rate
-        asm{rate} "sts UBRR0L, r24
-                   sts UBRR0H, r25
-                   ldi r24, (1 << TXEN0) | (1 << RXEN0)
-                   sts UCSR0B, r24
-                   ldi r24, 3 << UCSZ00
-                   sts UCSR0C, r24"
-        return self
-  end
-
-  func destr()
-        return self
-  end
-
-  func send(x)
-        waitfor not \
-                (((asm "lds   r24, UCSR0A
-                        ldi  r25, 0") >> 5) & 1)
-        asm{x} "sts UDR0, r24"
-  end
-
-  func available()
-        return (((asm "lds   r24, UCSR0A
-                       ldi  r25, 0") >> 7) & 1)
-  end
-
-  func recv()
-        return asm "lds r24, UDR0
-                    ldi r25, 0"
-  end
-
-  func write(s)
-        var i <- 0
-        var c <- str_get(s, 0)
-
-        while c do
-                self.send(c)
-                i ++ 1
-                c <- str_get(s, i)
-        done
-  end
-end

File stdlib/vect.mr

-##
-## vect.mr for Mara
-##  
-## Copyright (C) 2013 Pierre Surply
-## <pierre.surply@gmail.com>
-##
-## This file is part of Mara.
-##
-##    Mara is free software: you can redistribute it and/or modify
-##    it under the terms of the GNU General Public License as published by
-##    the Free Software Foundation, either version 3 of the License, or
-##    (at your option) any later version.
-##
-##    Mara is distributed in the hope that it will be useful,
-##    but WITHOUT ANY WARRANTY; without even the implied warranty of
-##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-##    GNU General Public License for more details.
-##
-##    You should have received a copy of the GNU General Public License
-##    along with Mara.  If not, see <http://www.gnu.org/licenses/>.
-##
-
-begin class
-  integer         length
-  undef           vect
-
-  func init(length)
-        self.length <- length
-        self.vect <- asm{length * 2} "rcall malloc"
-        return self
-  end
-
-  func destr()
-        asm{self.vect} "rcall free"
-        return self
-  end
-
-  func set(i, x)
-        asm{self.vect} "movw r30, r24"
-        asm{i << 1}    "add  r30, r24
-                        adc  r31, r25"
-        asm{x}         "st   Z, r24
-                        std  Z+1, r25"
-  end
-
-  func get(i)
-        asm{self.vect} "movw r30, r24"
-        asm{i << 1}    "add  r30, r24
-                        adc  r31, r25"
-        return asm     "ld   r24, Z
-                        ldd  r25, Z+1"
-  end
-
-  func fill(x)
-        for i <- 0 to self.length - 1 do
-                self.set(i, x)
-        done
-  end
-end

File term/Makefile

 ## <pierre.surply@gmail.com>
 ## 
 ## Started on  Sun Jan 20 12:24:46 2013 Pierre Surply
-## Last update Sun Feb  3 19:34:29 2013 Pierre Surply
+## Last update Sun Mar 24 09:48:38 2013 Pierre Surply
 ##
 
-MCU		= 328p
+MCU		= 644
+DEVPROG		= /dev/ttyUSB1
+DEVCOM		= /dev/ttyUSB0
 
 MARAC		= marac
 MFLAGS		= -mmcu atmega$(MCU) -v
 
 AVRDUDE		= avrdude
 PARTNO		= m$(MCU)
-DEV		= /dev/ttyUSB0
 PROG		= stk500
-AFLAGS		= -p $(PARTNO) -c $(PROG) -P $(DEV) -e
-FUSE		= -U lfuse:w:0xc6:m -U hfuse:w:0xd9:m
+AFLAGS		= -p $(PARTNO) -c $(PROG) -P $(DEVPROG) -e
+FUSE		= #-U lfuse:w:0xc6:m -U hfuse:w:0xd9:m
 
 MAIN		= main
 MAINHEX		= $(MAIN).hex
 dump: $(MAINHEX)
 	$(AVRDUDE) $(AFLAGS) $(FUSE) -U "flash:w:$<"
 
+term::
+	cu -l $(DEVCOM) -s 9600
+
 clean::
 	rm -f *~
 	$(MARAC) -clean

File term/atoi.mr

+# Atoi
+
+using cstring
+
+begin lib
+  func is_nbr(s)
+    var i <- 0
+    var c <- 0
+    var b <- 10
+    if str_get(s, 0) = '0' then
+      if str_get(s, 1) = 'x' then
+        b <- 16
+        i <- 2
+      elif str_get(s, 1) = 'b' then
+        b <- 2
+        i <- 2
+      endif
+    endif
+    c <- str_get(s, i)
+    while c do
+      if not ((b = 10 and '0' <= c  and c <= '9') or \
+              (b = 2 and ('0' = c  or c = '1')) or \
+              (b = 16 and (('0' <= c  and c <= '9') or \
+                          ('a' <= c  and c <= 'f') or \
+                          ('A' <= c  and c <= 'F')))) then
+        return false
+      endif
+      i ++ 1
+      c <- str_get(s, i)
+    done
+    return true
+  end
+
+  func atoi(s)
+    var i <- 0
+    var a <- 0
+    var c <- 0
+    if str_get(s, 0) = '0' and  \
+       str_get(s, 1) = 'x' then
+      i <- 2
+      c <- str_get(s, i)
+      while c do
+        a <<<< 4
+        if 'A' <= c and c <= 'F' then
+          c <- c - 'A' + 0xA
+        elif 'a' <= c and c <= 'f' then
+          c <- c - 'a' + 0xA
+        else
+          c <- c - '0'
+        endif
+        a || c
+        i ++ 1
+        c <- str_get(s, i)
+      done
+    elif str_get(s, 0) = '0' and  \
+         str_get(s, 1) = 'b' then
+      i <- 2
+      c <- str_get(s, i)
+      while c do
+        a <<<< 1
+        a || c - '0'
+        i ++ 1
+        c <- str_get(s, i)
+      done
+    else
+      while str_get(s, i) do
+        a ** 10
+        a ++ str_get(s, i) - '0'
+        i ++ 1
+      done
+    endif
+    return a
+  end
+end

File term/cstring.mr

+##
+## cstring.mr for Mara
+##  
+## Copyright (C) 2013 Pierre Surply
+## <pierre.surply@gmail.com>
+##
+## This file is part of Mara.
+##
+##    Mara is free software: you can redistribute it and/or modify
+##    it under the terms of the GNU General Public License as published by
+##    the Free Software Foundation, either version 3 of the License, or
+##    (at your option) any later version.
+##
+##    Mara is distributed in the hope that it will be useful,
+##    but WITHOUT ANY WARRANTY; without even the implied warranty of
+##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+##    GNU General Public License for more details.
+##
+##    You should have received a copy of the GNU General Public License
+##    along with Mara.  If not, see <http://www.gnu.org/licenses/>.
+##
+
+begin lib
+  func str_get(s, i)
+    asm{{cstring : s}} "movw r30, r24"
+    asm{i}             "add  r30, r24
+                        adc  r31, r25"
+    return asm         "ld   r24, Z
+                        ldi  r25, 0"
+  end
+
+  func str_set(s, i, x)
+    asm{{cstring : s}} "movw r30, r24"
+    asm{i}             "add  r30, r24
+                        adc  r31, r25"
+    asm{x}             "st   Z, r24"
+  end
+
+  func str_cmp(s, d)
+    var i <- 0
+    var cs <- str_get(s, 0)
+    var cd <- str_get(d, 0)
+    while cd and cs and cd = cs do
+      i ++ 1
+      cs <- str_get(s, i)
+      cd <- str_get(d, i)
+    done
+    return (cs - cd)
+  end
+end

File term/main.mr

 ## <pierre.surply@gmail.com>
 ## 
 ## Started on  Fri Jan 25 17:56:51 2013 Pierre Surply
-## Last update Tue Feb  5 13:09:49 2013 Pierre Surply
+## Last update Fri Mar 22 19:29:53 2013 Pierre Surply
 ##
 
 begin setup
-        PORTC.set_mode(0xFF)
-        PORTC.write(42)
+        PORTB.set_mode(0xFF)
+        PORTB.write(0xFF)
         var term <- new term(23)
         term.wait_start()
 end

File term/string.mr

+##
+## string.mr for Mara
+##  
+## Copyright (C) 2013 Pierre Surply
+## <pierre.surply@gmail.com>
+##
+## This file is part of Mara.
+##
+##    Mara is free software: you can redistribute it and/or modify
+##    it under the terms of the GNU General Public License as published by
+##    the Free Software Foundation, either version 3 of the License, or
+##    (at your option) any later version.
+##
+##    Mara is distributed in the hope that it will be useful,
+##    but WITHOUT ANY WARRANTY; without even the implied warranty of
+##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+##    GNU General Public License for more details.
+##
+##    You should have received a copy of the GNU General Public License
+##    along with Mara.  If not, see <http://www.gnu.org/licenses/>.
+##
+
+using cstring
+using list
+
+begin class
+  integer         size
+  cstring         s
+
+  func init(size)
+    self.size <- size
+    self.s <- asm{size} "call malloc"
+    str_set(self.s, 0, 0)
+    return self
+  end
+
+  func destr()
+    asm{self.s} "call free"
+    return self
+  end
+
+  func set(i, x)
+    str_set(self.s, i, x)
+  end
+
+  func get(i)
+    return str_get(self.s, i)
+  end
+
+  func length()
+    var i <- 0
+    while self[i] do
+      i ++ 1
+    done
+    return i
+  end
+
+  func write_from(s, n)
+    var i <- 0
+    var c <- str_get(s, i)
+    while c and (i + n) < (self.size - 1) do
+      c <- str_get(s, i)
+      str_set(self.s, i + n, c)
+      i ++ 1
+    done
+    str_set(self.s, i + n, 0)
+  end
+
+  func write(s)
+    self.write_from(s, 0)
+  end
+
+  func cat(s)
+    var i <- 0
+    while str_get(self.s, i) do
+      i ++ 1
+    done
+    self.write_from(s, i)
+  end
+
+  func append_char(c)
+    var i <- 0
+    while str_get(self.s, i) do
+      i ++ 1
+    done
+    if i + 1 < self.size then
+      str_set(self.s, i, c)
+      str_set(self.s, i + 1, 0)
+      return true
+    else
+      return false
+    endif
+  end
+
+  func delete_char()
+    var i <- 0
+    while str_get(self.s, i) do
+      i ++ 1
+    done
+    if i > 0 then
+      str_set(self.s, i-1, 0)
+      return true
+    endif
+    return false
+  end
+
+  func print_digit(i, shift)
+    var c <- 0
+    i <- (i bitrs shift) bitand 0xF
+    if i < 0xA then
+      c <- i + '0'
+    else
+      c <- i - 0xA + 'A'
+    endif
+    self.append_char(c)
+  end
+
+  func itoa_rec(i)
+    var c <- i % 10
+    if i > 0 then
+      self.itoa_rec(i / 10)
+      self.append_char(c + '0')
+    endif
+  end
+
+  func itoa(i)
+    self.set(0, 0)
+    if i = 0 then
+      self.append_char('0')
+    else
+      if i < 0 then
+        self.append_char('-')
+        i <- -i
+      endif
+      self.itoa_rec(i)
+    endif
+  end
+
+  func itoa_hex(i, digit)
+    self.set(0, 0)
+    for j <- 0 to digit - 1 do
+      self.print_digit(i, \
+                       (digit - j - 1) * 4)
+    done
+  end
+
+  func split(sep)
+    var l <- []
+    var i <- self.length() - 1
+    while i and (self[i] = sep) do
+      self.set(i, 0)
+      i -- 1
+    done
+    while i do
+      if self[i] = sep then
+        l.push({integer : self.s} + i + 1)
+        while self[i] = sep do
+          self.set(i, 0)
+          i -- 1
+        done
+      endif
+      i -- 1
+    done
+    l.push(self.s)
+    return l
+  end
+end

File term/term.mr

 ## <pierre.surply@gmail.com>
 ## 
 ## Started on  Fri Jan 25 17:57:37 2013 Pierre Surply
-## Last update Tue Feb  5 13:49:34 2013 Pierre Surply
+## Last update Sat Mar 23 23:55:27 2013 Pierre Surply
 ##
 
-uart    com
-string  in
-string  out
-
-func init(rate)
-        self.com <- new uart(rate)
-        self.in <- new string(32)
-        self.out <- new string(32)
-end
-
-func destr()
-        del self.com
-        del self.in
-        del self.out
-end
-
-func wait_start()
-        waitfor not self.com.available()
-        self.com.recv()
-        self.com.write("### Mara Terminal ###\n\r(C) Pierre Surply\n\r")
-end
-
-func prompt()
-        var c <- 0
-        self.in.set(1, 0)
-        self.com.write("> ")
-        while not (c = 13) do
-                waitfor not self.com.available()
-                c <- self.com.recv()
-                if not (c = 13) then
-                        self.com.send(c)
-                        self.in.set(0, c)
-                endif
-        done
-        self.com.write("\n\r")
-end
-
-func shell()
-        self.prompt()
-        if self.in.cmp("hello") = 0 then
-                self.com.write("Hello World !\n\r")
+using eeprom
+using atoi
+
+begin class
+  uart    com
+  string  buffer
+
+  func init(rate)
+    self.com <- new uart(rate)
+    self.buffer <- new string(64)
+    return self
+  end
+
+  func destr()
+    del self.com
+    del self.buffer
+    return self
+  end
+
+  func wait_start()
+    waitfor not self.com.available()
+    self.com.recv()
+    self.com.write("### Mara Terminal ###\n\r(C) Pierre Surply\n\rhttp://mara.psurply.com/\n\r")
+  end
+
+  func prompt()
+    var c <- 0
+    self.buffer.set(0, 0)
+    self.com.write("> ")
+    while not (c = 13) do
+      waitfor not self.com.available()
+      c <- self.com.recv()
+      if c = 0x7F then
+        if self.buffer.delete_char() then
+          self.com.send(c)
+        endif
+      elif not c = 13 then
+        if self.buffer.append_char(c) then
+          self.com.send(c)
+          PORTB.write(~c)
+        endif
+      endif
+    done
+    self.com.newline()
+  end
+
+  func print(arg)
+    var larg <- {list : arg}
+    for i <- 1 to arg.length - 1 do
+      self.com.send('[')
+      self.com.write(arg[i])
+      self.com.write("] ")
+    done
+    self.com.newline()
+  end
+
+  func romr(arg)
+    var larg <- {list : arg}
+    var l <- 1
+    var addr <- atoi(arg[1])
+    if arg.length >= 3 then
+      l <- atoi(arg[2])
+    endif
+    for i <- 0 to l - 1 do
+      if not (i & 0x7) then
+        self.buffer.itoa_hex(addr + i, 4)
+        self.com.write(self.buffer.s)
+        self.com.send(':')
+      endif
+      self.com.send(' ')
+      self.buffer.itoa_hex(eeprom_read(addr + i), 2)
+      self.com.write(self.buffer.s)
+      if not ((i + 1) & 0x7) then
+        self.com.newline()
+      endif
+    done
+    self.com.newline()
+  end
+
+  func shell()
+    self.prompt()
+    if self.buffer[0] then
+      var arg <- self.buffer.split(' ')
+      if str_cmp(arg[0], "hello") = 0 then
+        self.com.write("Hello World !\n\r")
+      elif str_cmp(arg[0], "quit") = 0 then
+        self.com.write("Bye !\n\r")
+        asm "ldi   r24, (1 << SE)
+             out   SMCR, r24
+             sleep"
+      elif str_cmp(arg[0], "print") = 0 then
+        self.print(arg)
+      elif str_cmp(arg[0], "run") = 0 then
+        var umara <- new umara(arg, new vect(64), self.com, self.buffer)
+        if umara.compile() then
+          umara.run()
+        endif
+        del umara
+      elif str_cmp(arg[0], "debug") = 0 then
+        umara <- new umara(arg, new vect(64), self.com, self.buffer)
+        if umara.compile() then
+          umara.debug()
+        endif
+        del umara
+      elif str_cmp(arg[0], "romw") = 0 then
+        if arg.length >= 3 then
+          eeprom_write(atoi(arg[1]), atoi(arg[2]))
+        else
+          self.com.write("usage : romw ADDR DATA\n\r")
+        endif
+      elif str_cmp(arg[0], "romr") = 0 then
+        if arg.length >= 2 then
+          self.romr(arg)
         else
-                self.com.write("Command not found [")
-                self.com.write(self.in.s)
-                self.com.write("]\n\r")
+          self.com.write("usage : romr ADDR [LENGTH]\n\r")
         endif
+      else
+        self.com.write(arg[0])
+        self.com.write(" : Command not found\n\r")
+      endif
+      del arg
+    endif
+  end
 end

File term/uart.mr

+# UART
+
+using cstring
+
+begin class
+  integer rate
+
+  func init(rate)
+    self.rate <- rate
+    asm{rate} "sts UBRR0L, r24
+               sts UBRR0H, r25
+               ldi r24, (1 << TXEN0) | (1 << RXEN0)
+               sts UCSR0B, r24
+               ldi r24, (3 << UCSZ00)
+               sts UCSR0C, r24"
+    return self
+  end
+
+  func destr()
+    return self
+  end
+
+  func send(x)
+    waitfor not \
+      (((asm "lds   r24, UCSR0A
+              clr  r25") >> 5) & 1)
+    asm{x} "sts UDR0, r24"
+  end
+
+  func available()
+    return (((asm "lds   r24, UCSR0A
+                   clr  r25") >> 7) & 1)
+  end
+
+  func recv()
+    return asm "lds  r24, UDR0
+                clr r25"
+  end
+
+  func write(s)
+    var i <- 0
+    var c <- str_get(s, 0)
+
+    while c do
+      self.send(c)
+      i ++ 1
+      c <- str_get(s, i)
+    done
+  end
+
+  func newline()
+    self.write("\n\r")
+  end
+end

File term/umara.mr

+# uMara
+
+using cstring
+using atoi
+
+begin class
+  uart          com
+  vect          mem
+  vm            vm
+  integer       size
+  list          arg
+  string        buffer
+
+  func init(arg, mem, com, buffer)
+    self.buffer <- buffer
+    self.arg <- arg
+    self.mem <- mem
+    self.com <- com
+    self.vm <- none
+    self.size <- 0
+    return self
+  end
+
+  func destr()
+    del self.vm
+    return self
+  end
+
+  func make_instr(op, dst, src)
+    return (op bitls 8) bitor (dst bitls 2) bitor src
+  end
+
+  func add_byte(byte)
+    self.mem.set(self.size, byte)
+    self.size ++ 1
+  end
+
+  func compile()
+    var op <- 0
+    for i <- 1 to self.arg.length - 1 do
+      op <- str_get(self.arg[i], 0)
+      if is_nbr(self.arg[i]) then
+        self.add_byte(self.make_instr(20, 0, 0))
+        self.add_byte(atoi(self.arg[i]))
+        self.add_byte(self.make_instr(1, 0, 0))
+      elif op = '+' then
+        self.add_byte(self.make_instr(2, 0, 1))
+        self.add_byte(self.make_instr(2, 0, 0))
+        self.add_byte(self.make_instr(5, 0, 1))
+        self.add_byte(self.make_instr(1, 0, 0))
+      elif op = '-' then
+        self.add_byte(self.make_instr(2, 0, 1))
+        self.add_byte(self.make_instr(2, 0, 0))
+        self.add_byte(self.make_instr(6, 0, 1))
+        self.add_byte(self.make_instr(1, 0, 0))
+      elif op = '*' then
+        self.add_byte(self.make_instr(2, 0, 1))
+        self.add_byte(self.make_instr(2, 0, 0))
+        self.add_byte(self.make_instr(7, 0, 1))
+        self.add_byte(self.make_instr(1, 0, 0))
+      elif op = '/' then
+        self.add_byte(self.make_instr(2, 0, 1))
+        self.add_byte(self.make_instr(2, 0, 0))
+        self.add_byte(self.make_instr(8, 0, 1))
+        self.add_byte(self.make_instr(1, 0, 0))
+      elif op = '%' then
+        self.add_byte(self.make_instr(2, 0, 1))
+        self.add_byte(self.make_instr(2, 0, 0))
+        self.add_byte(self.make_instr(9, 0, 1))
+        self.add_byte(self.make_instr(1, 0, 0))
+      elif op = '.' then
+        self.add_byte(self.make_instr(2, 0, 0))
+        self.add_byte(self.make_instr(3, 0, 0))
+      else
+        self.com.write("Syntax error")
+        self.com.newline()
+        return false
+      endif
+    done
+    self.add_byte(0xFFFF)
+    return true
+  end
+
+  func run()
+    self.vm <- new vm(self.mem, self.com)
+    self.vm.max_sp <- self.size
+    waitfor self.vm.exec()
+    self.com.newline()
+  end
+
+  func debug()
+    self.vm <- new vm(self.mem, self.com)
+    self.vm.max_sp <- self.size
+    var d <- 0
+    var c <- true
+    while c do
+      for i <- 0 to 3 do
+        self.buffer.itoa_hex(self.vm.reg[i], 4)
+        self.com.write(self.buffer.s)
+        self.com.send(' ')
+      done
+      self.com.newline()
+      for y <- 0 to 7 do
+        for x <- 0 to 7 do
+          d <- x + y * 8
+          if self.vm.pc = d or self.vm.sp = d then
+            self.com.send('[')
+          else
+            self.com.send(' ')
+          endif
+          self.buffer.itoa_hex(self.mem[d], 4)
+          self.com.write(self.buffer.s)
+          if self.vm.pc = d or self.vm.sp = d then
+            self.com.send(']')
+          else
+            self.com.send(' ')
+          endif
+        done
+        self.com.newline()
+      done
+      self.com.newline()
+      waitfor not self.com.available()
+      self.com.recv()
+      c <- self.vm.exec()
+    done
+  end
+end

File term/vect.mr

+##
+## vect.mr for Mara
+##  
+## Copyright (C) 2013 Pierre Surply
+## <pierre.surply@gmail.com>
+##
+## This file is part of Mara.
+##
+##    Mara is free software: you can redistribute it and/or modify
+##    it under the terms of the GNU General Public License as published by
+##    the Free Software Foundation, either version 3 of the License, or
+##    (at your option) any later version.
+##
+##    Mara is distributed in the hope that it will be useful,
+##    but WITHOUT ANY WARRANTY; without even the implied warranty of
+##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+##    GNU General Public License for more details.
+##
+##    You should have received a copy of the GNU General Public License
+##    along with Mara.  If not, see <http://www.gnu.org/licenses/>.
+##
+
+begin class
+  integer         length
+  undef           vect
+
+  func init(length)
+    self.length <- length
+    self.vect <- asm{length * 2} "call malloc"
+    return self
+  end
+
+  func destr()
+    asm{self.vect} "call free"
+    return self
+  end
+
+  func set(i, x)
+    asm{self.vect} "movw r30, r24"
+    asm{i << 1}    "add  r30, r24
+                    adc  r31, r25"
+    asm{x}         "st   Z, r24
+                    std  Z+1, r25"
+  end
+
+  func get(i)
+    asm{self.vect} "movw r30, r24"
+    asm{i << 1}    "add  r30, r24
+                    adc  r31, r25"
+    return asm     "ld   r24, Z
+                    ldd  r25, Z+1"
+  end
+
+  func fill(x)
+    for i <- 0 to self.length - 1 do
+      self.set(i, x)
+    done
+  end
+end
+# uMara VM
+
+begin class
+  vect          mem
+  vect          reg
+  integer       pc
+  integer       sp
+  integer       max_sp
+  uart          com
+  string        buffer
+
+  func init(mem, com)
+    self.mem <- mem
+    self.reg <- new vect(4)
+    self.pc <- 0
+    self.sp <- self.mem.length - 1
+    self.buffer <- new string(64)
+    self.max_sp <- 0
+
+    return self
+  end
+
+  func destr()
+    del self.reg
+    del self.mem
+    del self.buffer
+    return self
+  end
+
+  func exec()
+    var instr <- self.mem[self.pc]
+    var op <- instr bitrs 8
+    var mode <- instr bitand 0x00FF
+    var src <- instr bitand 0x0003
+    var dst <- (instr bitand 0x000C) bitrs 2
+    
+    if op = 20 then # load
+      self.reg.set(src, self.mem[self.pc + 1])
+      self.pc ++ 1
+    elif op = 1 then # push
+      self.mem.set(self.sp, self.reg[src])
+      self.sp -- 1
+      if self.sp < self.max_sp then
+        self.com.write("VM error : Stack overflow")
+        return false
+      endif
+    elif op = 2 then # pop
+      self.sp ++ 1
+      if self.sp >= self.mem.length then
+        self.com.write("VM error : The stack is empty")
+        return false
+      else
+        self.reg.set(src, self.mem[self.sp])
+      endif
+    elif op = 3 then # print_int
+      self.buffer.itoa(self.reg[src])
+      self.com.write(self.buffer.s)
+    elif op = 4 then # print_ascii
+      self.com.send(self.reg[src])
+    elif op = 5 then # add
+      self.reg.set(dst, (self.reg[src]) + (self.reg[dst]))
+    elif op = 6 then # sub
+      self.reg.set(dst, (self.reg[dst]) - (self.reg[src]))
+    elif op = 7 then # mul
+      self.reg.set(dst, (self.reg[dst]) * (self.reg[src]))
+    elif op = 8 then # div
+      self.reg.set(dst, (self.reg[dst]) / (self.reg[src]))
+    elif op = 9 then # mod
+      self.reg.set(dst, (self.reg[dst]) % (self.reg[src]))
+    elif op = 10 then # ls
+      self.reg.set(dst, (self.reg[dst]) bitls (self.reg[src]))
+    elif op = 11 then # rs
+      self.reg.set(dst, (self.reg[dst]) bitrs (self.reg[src]))
+    elif op = 12 then # bitand
+      self.reg.set(dst, (self.reg[dst]) bitand (self.reg[src]))
+    elif op = 13 then # bitor
+      self.reg.set(dst, (self.reg[dst]) bitor (self.reg[src]))
+    elif op = 14 then # and
+      self.reg.set(dst, (self.reg[dst]) and (self.reg[src]))
+    elif op = 15 then # or
+      self.reg.set(dst, (self.reg[dst]) or (self.reg[src]))
+    elif op = 16 then # compl
+      self.reg.set(src, compl (self.reg[src]))
+    elif op = 17 then # not
+      self.reg.set(src, not (self.reg[src]))
+    elif instr = 0xFFFF then
+      return false
+    elif instr <> 0 then
+      self.buffer.itoa_hex(instr, 4)
+      self.com.write("VM error : unknown instruction $")
+      self.com.write(self.buffer.s)
+      return false
+    endif
+    self.pc ++ 1
+    return true
+  end
+end

File utils/mara-mode.el

 ;; <pierre.surply@gmail.com>
 ;; 
 ;; Started on  Sat Jan 19 16:37:09 2013 Pierre Surply
-;; Last update Fri Mar 15 14:46:26 2013 Pierre Surply
+;; Last update Sat Mar 16 22:38:59 2013 Pierre Surply
 ;;
 
 
     "downto"
     "var"
     "return"
+    "bitls"
+    "bitrs"
+    "bitor"
+    "bitand"
+    "compl"
     "and"
     "or"
     "not")

File website/cgi-bin/env.ml

 **    along with OCaml-WebFramework.  If not, see <http://www.gnu.org/licenses/>.
 ** 
 ** Started on  Sun Sep 16 13:57:47 2012 Pierre Surply
-** Last update Sun Feb 10 14:44:08 2013 Pierre Surply
+** Last update Sat Mar 16 15:47:38 2013 Pierre Surply
 *)
 
 let get_env str =

File website/cgi-bin/highlight.ml

+(*
+** highlight.ml for Mara
+** 
+** Made by Pierre Surply
+** <pierre.surply@gmail.com>
+** 
+** Started on  Sat Mar 16 14:58:18 2013 Pierre Surply
+** Last update Tue Mar 26 08:23:20 2013 Pierre Surply
+*)
+
+let code_dir = "../res/code/"
+let regex_struct_kw = Str.regexp
+  begin
+    "\\("                       ^
+      "\\bbegin\\b\\|"          ^
+      "\\bend\\b\\|"            ^
+      "\\bfunc\\b\\|"           ^
+      "\\bstate\\b\\|"          ^
+      "\\baction\\b\\|"         ^
+      "\\binput\\b\\|"          ^
+      "\\bstatic\\b\\|"         ^
+      "\\bfsm\\b\\|"            ^
+      "\\busing\\b\\)"
+  end
+let regex_kw = Str.regexp
+  begin
+    "\\("                       ^
+      "\\bif\\b\\|"             ^
+      "\\bthen\\b\\|"           ^
+      "\\belse\\b\\|"           ^
+      "\\bendif\\b\\|"          ^
+      "\\belif\\b\\|"           ^
+      "\\bwhile\\b\\|"          ^
+      "\\bwaitfor\\b\\|"        ^
+      "\\bfor\\b\\|"            ^
+      "\\bto\\b\\|"             ^
+      "\\bdone\\b\\|"           ^
+      "\\bdownto\\b\\|"         ^
+      "\\bdo\\b\\|"             ^
+      "\\breturn\\b\\|"         ^
+      "\\band\\b\\|"            ^
+      "\\bor\\b\\|"             ^
+      "\\bnot\\b\\|"            ^
+      "\\bbitls\\b\\|"          ^
+      "\\bbitrs\\b\\|"          ^
+      "\\bbitor\\b\\|"          ^
+      "\\bbitand\\b\\|"         ^
+      "\\bcompl\\b\\|"          ^
+      "\\bnew\\b\\|"            ^
+      "\\bdel\\b\\|"            ^
+      "\\basm\\b\\|"            ^
+      "\\bvar\\b\\)"
+  end
+let regex_types = Str.regexp
+  begin
+    "\\("                       ^
+      "\\binteger\\b\\|"        ^
+      "\\bundef\\b\\|"          ^
+      "\\bcstring\\b\\|"        ^
+      "\\bstring\\b\\|"         ^
+      "\\blist\\b\\)"
+  end
+let regex_const = Str.regexp
+  begin
+    "\\("                       ^
+      "\\bself\\|"              ^
+      "\\btrue\\b\\|"           ^
+      "\\bfalse\\b\\|"          ^
+      "\\bnone\\b\\|"           ^
+      "\\bPORTA\\|"             ^
+      "\\bPORTB\\|"             ^
+      "\\bPORTC\\|"             ^
+      "\\bPORTD\\)"
+  end
+let regex_comment = Str.regexp "\\(#.*\\|\".*\"\\)"
+let regex_lt = Str.regexp "<"
+let regex_gt = Str.regexp ">"
+let regex_lb = Str.regexp "\\["
+let regex_rb = Str.regexp "\\]"
+
+let span span s =
+  "<span class=\"" ^ span ^ "\">" ^ (Str.matched_group 1 s) ^ "</span>"
+
+let struct_kw s = span "structkw" s
+let kw s        = span "kw" s
+let types s     = span "types" s
+let const s     = span "const" s
+let comment s   = span "comment" s
+
+let apply s =
+  let rec r_load_template f =
+    try
+      let s = input_line f in
+      let s = Str.global_replace regex_lt "&lt;" s in
+      let s = Str.global_replace regex_gt "&gt;" s in
+      let s_comment = Str.global_substitute regex_comment comment s in
+      let s_struct_kw = Str.global_substitute regex_struct_kw struct_kw s_comment in
+      let s_kw = Str.global_substitute regex_kw kw s_struct_kw in
+      let s_types = Str.global_substitute regex_types types s_kw in
+      let s_const = Str.global_substitute regex_const const s_types in
+      let s = Str.global_replace regex_lb "&#91;" s_const in
+      let s = Str.global_replace regex_rb "&#93;" s in
+      s ^ "\n" ^ r_load_template f
+    with End_of_file -> close_in f; ""
+  in
+  let file = open_in (code_dir ^ Str.matched_group 1 s) in
+  "<pre>\n<code>\n" ^ r_load_template file ^ "</code>\n</pre>\n"

File website/cgi-bin/template.ml

 **    along with OCaml-WebFramework.  If not, see <http://www.gnu.org/licenses/>.
 **
 ** Started on  Sat Sep 15 13:45:19 2012 Pierre Surply
-** Last update Fri Mar 15 15:52:27 2013 Pierre Surply
+** Last update Sat Mar 16 15:16:31 2013 Pierre Surply
 *)
 
 let template_dir = "../templates/"
 let regex_include = Str.regexp "{ \\([^{}]*\\) }"
 let regex_part = Str.regexp
   "\\[begin \\(.*\\)\\]\\(\\([^][]\\|\n\\)*\\)\\[end\\]"
+let regex_code = Str.regexp "{\\$ \\(.*\\) \\$}"
 
 let apply_function s =
   Cgi_functions.get_function (Str.matched_group 1 s)
   in
   let rec r_load file part=
     let s = r_load_template (open_in (template_dir ^ file)) in
+    let s_applied_highlight = Str.global_substitute regex_code
+      Highlight.apply s in
     let s_applied_fun = Str.global_substitute regex_fun
-      apply_function s in
+      apply_function s_applied_highlight in
     let s_filled = Str.global_substitute regex_include
       (fill_part part) s_applied_fun in
     let part = extract_part s_filled 0 part in

File website/res/code/alt.mr

+begin setup
+  var a <- 42
+  var b <- 0
+
+  if a = 1 then
+    b <- 21
+  elif a <> 2 then
+    b <- 1337
+  else
+    b <- 0
+  endif
+  # Here, b = 1337
+end
+  
+begin loop
+end

File website/res/code/arith.mr

+begin setup
+  var a <- 7
+  var b <- 3
+  var c <- 0
+
+  c <- a + b      # c = 10
+  c <- a - b      # c = 4
+  c <- a * b * 2  # c = 42
+  c <- a / b      # c = 2
+  c <- a % b      # c = 1
+end
+  
+begin loop
+end

File website/res/code/asm.mr

+begin setup
+  var a <- 40
+  var b <- asm{a + 1} "inc r24" # b = 42
+end
+
+begin loop
+end

File website/res/code/assign.mr

+begin setup
+  var a <- 0
+
+  a <- 6
+  a <- a * 7      # a = 42
+end
+  
+begin loop
+end

File website/res/code/bitop.mr

+begin setup
+  var a <- 0x002A
+  var b <- 0x000F
+  var c <- 0
+
+  c <- a bitand b       # c = 0b00001010
+  c <- a bitor b        # c = 0b00101111
+  c <- compl b          # c = 0xFFF0
+  c <- a bitrs 1        # c = 0b00010101
+  c <- a bitls 2        # c = 0b10101000
+end
+  
+begin loop
+end

File website/res/code/blink.mr

+using delay                   # Import libraries used here        
+
+begin setup
+  PORTC.set_pin_out(0)        # Setup PC0 as an output
+end
+
+begin loop                    # Repeat forever the following statement :
+  PORTC.pin_high(0)           #   Set PC0 high
+  delay(1)                    #   Wait a few moment
+  PORTC.pin_low(0)            #   Set PC0 low
+  delay(1)                    #   Wait a few moment
+end

File website/res/code/boolop.mr

+begin setup
+  var a <- 7
+  var b <- 3
+  var c <- 0
+
+  c <- a and b                    # c = 1
+  c <- (a = 3) or (b <> 7)        # c = 1
+  c <- not b                      # c = 0
+end
+  
+begin loop
+end

File website/res/code/character.mr

+# character.mr
+
+begin class
+  string first_name
+  string last_name
+
+  func init(fname, lname)
+    self.first_name <- new string(32)
+    self.last_name <- new string(32)
+
+    self.first_name.write(fname)
+    self.last_name.write(lname)
+
+    return self
+  end
+
+  func destr()
+    del self.first_name
+    del self.last_name