new files of 0.5.2
[fw/sdcc] / sim / ucsim / cmd.src / cmdpars.y
diff --git a/sim/ucsim/cmd.src/cmdpars.y b/sim/ucsim/cmd.src/cmdpars.y
new file mode 100644 (file)
index 0000000..2b106ac
--- /dev/null
@@ -0,0 +1,154 @@
+%name cl_ucsim_parser
+
+%{
+#include "cmdlexcl.h"
+#include "memcl.h"
+#include "globals.h"
+#include "stypes.h"
+%}
+
+%pure_parser
+
+%define INHERIT : public cl_base
+
+%define MEMBERS class cl_ucsim_lexer *lexer_object;\
+virtual ~YY_cl_ucsim_parser_CLASS(void) { delete lexer_object; }
+
+%define CONSTRUCTOR_PARAM \
+class cl_ucsim_lexer *the_lexer
+
+%define CONSTRUCTOR_CODE \
+lexer_object= the_lexer;
+
+%token PTOK_PLUS PTOK_MINUS PTOK_ASTERIX PTOK_SLASH PTOK_EQUAL
+%token PTOK_LEFT_PAREN PTOK_RIGHT_PAREN
+%token PTOK_LEFT_BRACKET PTOK_RIGHT_BRACKET
+%token PTOK_DOT PTOK_AMPERSAND
+
+%token <memory_object> PTOK_MEMORY_OBJECT
+%token <memory> PTOK_MEMORY
+%token <number> PTOK_NUMBER
+%token <bit> PTOK_BIT
+
+%right PTOK_EQUAL
+%left PTOK_MINUS PTOK_PLUS
+%left PTOK_ASTERIX PTOK_SLASH
+%nonassoc UNARYMINUS PTOK_AMPERSAND
+%nonassoc PTOK_LEFT_PAREN PTOK_RIGHT_PAREN
+
+%type <number> ucsim_grammar assignment expression address_of_expression
+%type <memory> memory
+%type <bit> bit
+
+%union {
+  long number;
+  class cl_memory *memory_object;
+  struct {
+    class cl_memory *memory;
+    long address;
+  } memory;
+  struct {
+    class cl_memory *memory;
+    long mem_address, bit_address;
+    long mask;
+  } bit;
+}
+
+%%
+
+ucsim_grammar:
+       expression { application->dd_printf("%d\n", $1); }
+       ;
+
+assignment:
+         memory PTOK_EQUAL expression
+         {
+           $1.memory->write($1.address, $3);
+           $$= $3;
+         }
+       | bit PTOK_EQUAL expression
+         {
+           if ($3)
+             {
+               $1.memory->write($1.mem_address,
+                                $1.memory->read($1.mem_address) | $1.mask);
+               $$= 1;
+             }
+           else
+             {
+               $1.memory->write($1.mem_address,
+                                $1.memory->read($1.mem_address) & ~($1.mask));
+               $$= 0;
+             }
+         }
+       ;
+
+expression:
+         assignment { $$= $1; }
+       | expression PTOK_PLUS expression { $$= $1 + $3; }
+       | expression PTOK_MINUS expression { $$= $1 - $3; }
+       | expression PTOK_ASTERIX expression { $$= $1 * $3; }
+       | expression PTOK_SLASH expression
+         {
+           if ($3 == 0)
+             yyerror("Divide by zero");
+           else
+             $$= $1 / $3;
+         }
+       | PTOK_MINUS expression %prec UNARYMINUS { $$= -$2; }
+       | address_of_expression { $$= $1; }
+       | PTOK_LEFT_PAREN expression PTOK_RIGHT_PAREN { $$= $2; }
+       | PTOK_NUMBER { $$= $1; }
+       | memory { $$= $1.memory->read($1.address); }
+       | bit { $$= ($1.memory->read($1.mem_address) & $1.mask)?1:0; }
+       ;
+
+address_of_expression:
+         PTOK_AMPERSAND memory { $$= $2.address; }
+       | PTOK_AMPERSAND bit
+       {
+         $$= $2.bit_address;
+         if ($$ < 0)
+           {
+             yyerror("Bit has no address.");
+             $$= 0;
+           }
+       }
+       ;
+
+memory:
+         PTOK_MEMORY
+       | PTOK_MEMORY_OBJECT PTOK_LEFT_BRACKET expression PTOK_RIGHT_BRACKET
+         {
+           $$.memory= $1;
+           $$.address= $3;
+         }
+
+bit:
+         PTOK_BIT
+       | memory PTOK_DOT expression
+         {
+           $$.memory= $1.memory;
+           $$.mem_address= $1.address;
+           $$.mask= 1 << $3;
+           $$.bit_address= -1;
+           class cl_uc *uc= application->get_uc();
+           if (uc)
+             $$.bit_address= uc->bit_address($1.memory, $1.address, $3);
+         }
+       ;
+
+%%
+
+int
+YY_cl_ucsim_parser_CLASS::yylex(YY_cl_ucsim_parser_STYPE *yylval)
+{
+  lexer_object->activate_lexer_to_parse_into(yylval);
+  return(lexer_object->yylex());
+}
+
+void
+YY_cl_ucsim_parser_CLASS::yyerror(char *msg)
+{
+  application->dd_printf("Parser error: %s\n", msg);
+}