summaryrefslogtreecommitdiff
path: root/sim/ucsim/cmd.src/cmdpars.y
diff options
context:
space:
mode:
authorXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
committerXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
commit268a53de823a6750d6256ee1fb1e7707b4b45740 (patch)
tree42c1799a9a82b2f7d9790ee9fe181d72a7274751 /sim/ucsim/cmd.src/cmdpars.y
downloadsdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'sim/ucsim/cmd.src/cmdpars.y')
-rw-r--r--sim/ucsim/cmd.src/cmdpars.y418
1 files changed, 418 insertions, 0 deletions
diff --git a/sim/ucsim/cmd.src/cmdpars.y b/sim/ucsim/cmd.src/cmdpars.y
new file mode 100644
index 0000000..48f0439
--- /dev/null
+++ b/sim/ucsim/cmd.src/cmdpars.y
@@ -0,0 +1,418 @@
+%{
+
+#include "cmdlexcl.h"
+#include "memcl.h"
+#include "globals.h"
+#include "stypes.h"
+
+static void yyerror (const char *msg);
+%}
+/*%expect 6*/
+
+%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 PTOK_PIPE PTOK_CIRCUM
+%token PTOK_PERCENT PTOK_TILDE PTOK_QUESTION PTOK_COLON PTOK_EXCLAMATION
+%token PTOK_LESS PTOK_GREATHER PTOK_COMMA
+
+%token PTOK_AND_OP PTOK_OR_OP
+%token PTOK_INC_OP PTOK_DEC_OP
+%token PTOK_EQ_OP PTOK_NE_OP
+%token PTOK_GE_OP PTOK_LE_OP
+%token PTOK_LEFT_OP PTOK_RIGHT_OP
+
+%token PTOK_MUL_ASSIGN
+%token PTOK_DIV_ASSIGN
+%token PTOK_MOD_ASSIGN
+%token PTOK_ADD_ASSIGN
+%token PTOK_SUB_ASSIGN
+%token PTOK_LEFT_ASSIGN
+%token PTOK_RIGHT_ASSIGN
+%token PTOK_AND_ASSIGN
+%token PTOK_XOR_ASSIGN
+%token PTOK_OR_ASSIGN
+
+%token PTOK_INT
+
+%token <memory_object> PTOK_MEMORY_OBJECT
+%token <memory> PTOK_MEMORY
+%token <number> PTOK_NUMBER
+%token <bit> PTOK_BIT
+
+%type <number> ucsim_grammar expr
+%type <number> primary_expr postfix_expr
+%type <number> unary_expr cast_expr
+%type <number> multiplicative_expr additive_expr shift_expr
+%type <number> relational_expr equality_expr
+%type <number> and_expr exclusive_or_expr inclusive_or_expr
+%type <number> logical_and_expr logical_or_expr
+%type <number> conditional_expr assignment_expr
+
+%type <number> type_name assignment_operator
+
+%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:
+expr { application->/*dd_printf("%d\n", $1)*/expr_result=$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;
+ }
+ }
+ ;
+*/
+
+
+primary_expr
+/* : identifier */
+: memory { $$= $1.memory->read($1.address); }
+| bit { $$= ($1.memory->read($1.mem_address) & $1.mask)?1:0; }
+| PTOK_NUMBER { $$= $1; }
+ /* | string_literal_val*/
+| PTOK_LEFT_PAREN expr PTOK_RIGHT_PAREN { $$= $2; }
+ /* | generic_selection*/
+ ;
+
+postfix_expr
+: primary_expr { $$= $1; }
+/* | postfix_expr PTOK_LEFT_BRACKET expr PTOK_RIGHT_BRACKET */
+/* | postfix_expr PTOK_LEFT_PAREN PTOK_RIGHT_PAREN */
+/* | postfix_expr PTOK_LEFT_PAREN argument_expr_list PTOK_RIGHT_PAREN*/
+/* | postfix_expr PTOK_DOT identifier*/
+/* | postfix_expr PTOK_AMPERSAND identifier*/
+/*| postfix_expr PTOK_INC_OP*/
+| memory PTOK_INC_OP
+ {
+ $$= $1.memory->read($1.address);
+ $1.memory->write($1.address, $$+1);
+ }
+/*| postfix_expr PTOK_DEC_OP*/
+| memory PTOK_DEC_OP
+ {
+ $$= $1.memory->read($1.address);
+ $1.memory->write($1.address, $$-1);
+ }
+;
+/*
+argument_expr_list
+ : assignment_expr
+ | assignment_expr PTOK_COLON argument_expr_list
+ ;
+*/
+
+unary_expr
+: postfix_expr { $$= $1; }
+/*| PTOK_INC_OP unary_expr */
+| PTOK_INC_OP memory
+ {
+ $$= $2.memory->read($2.address);
+ $2.memory->write($2.address, $$+1);
+ $$= $2.memory->read($2.address);
+ }
+/*| PTOK_DEC_OP unary_expr */
+| PTOK_DEC_OP memory
+ {
+ $$= $2.memory->read($2.address);
+ $2.memory->write($2.address, $$-1);
+ $$= $2.memory->read($2.address);
+ }
+/*| unary_operator cast_expr */
+/*| PTOK_AMPERSAND unary_expr*/
+|PTOK_AMPERSAND memory { $$= $2.address; }
+|PTOK_AMPERSAND bit
+ {
+ $$= $2.bit_address;
+ if ($$ < 0)
+ {
+ yyerror("Bit has no address.");
+ $$= 0;
+ }
+ }
+| PTOK_MINUS unary_expr { $$= -$2; }
+| PTOK_PLUS unary_expr { $$= +$2; }
+| PTOK_TILDE unary_expr { $$= ~$2; }
+| PTOK_EXCLAMATION unary_expr { $$= ($2)?0:1; }
+ /* | SIZEOF unary_expr */
+ /* | SIZEOF PTOK_LEFT_PAREN type_name PTOK_RIGHT_PAREN */
+ /* | ALIGNOF PTOK_LEFT_PAREN type_name PTOK_RIGHT_PAREN*/
+ /* | TYPEOF unary_expr */
+ /* | OFFSETOF PTOK_LEFT_PAREN type_name PTOK_COMMA offsetof_member_designator PTOK_RIGHT_PAREN */
+;
+
+/*
+unary_operator
+ : '&'
+ | '*'
+ | '+'
+ | '-'
+ | '~'
+ | '!'
+ ;
+*/
+
+cast_expr
+: unary_expr { $$= $1; }
+| PTOK_LEFT_PAREN type_name PTOK_RIGHT_PAREN /*cast_expr*/ memory
+ {
+ $$= $4.memory->read($4.address);
+ if ($2 == PTOK_INT)
+ {
+ // If the highest bit for the memory width is set
+ // sign extend by setting all the bits above that.
+ long smask= 1U << ($4.memory->width - 1);
+ if ($$ & smask)
+ $$ |= ~(smask - 1);
+ }
+ }
+;
+
+type_name
+: PTOK_INT { $$= PTOK_INT; }
+;
+
+multiplicative_expr
+: cast_expr { $$= $1; }
+| multiplicative_expr PTOK_ASTERIX cast_expr { $$= $1 * $3; }
+| multiplicative_expr PTOK_SLASH cast_expr { $$= $1 / $3; }
+| multiplicative_expr PTOK_PERCENT cast_expr { $$= $1 % $3; }
+;
+
+additive_expr
+: multiplicative_expr { $$= $1; }
+| additive_expr PTOK_PLUS multiplicative_expr { $$= $1 + $3; }
+| additive_expr PTOK_MINUS multiplicative_expr { $$= $1 - $3; }
+;
+
+shift_expr
+: additive_expr { $$= $1; }
+| shift_expr PTOK_LEFT_OP additive_expr { $$= $1 << $3; }
+| shift_expr PTOK_RIGHT_OP additive_expr { $$= $1 >> $3; }
+;
+
+relational_expr
+: shift_expr { $$= $1; }
+| relational_expr PTOK_LESS shift_expr { $$= ($1 < $3)?1:0; }
+| relational_expr PTOK_GREATHER shift_expr { $$= ($1 > $3)?1:0; }
+| relational_expr PTOK_LE_OP shift_expr { $$= ($1 <= $3)?1:0; }
+| relational_expr PTOK_GE_OP shift_expr { $$= ($1 >= $3)?1:0; }
+;
+
+equality_expr
+: relational_expr { $$= $1; }
+| equality_expr PTOK_EQ_OP relational_expr { $$= ($1==$3)?1:0; }
+| equality_expr PTOK_NE_OP relational_expr { $$= ($1!=$3)?1:0; }
+;
+
+and_expr
+: equality_expr { $$= $1; }
+| and_expr PTOK_AMPERSAND equality_expr { $$= $1 & $3; }
+;
+
+exclusive_or_expr
+: and_expr { $$= $1; }
+| exclusive_or_expr PTOK_CIRCUM and_expr { $$= $1 ^ $3; }
+;
+
+inclusive_or_expr
+: exclusive_or_expr { $$= $1; }
+| inclusive_or_expr PTOK_PIPE exclusive_or_expr { $$= $1 | $3; }
+;
+
+logical_and_expr
+: inclusive_or_expr { $$= $1; }
+| logical_and_expr PTOK_AND_OP inclusive_or_expr { $$= ($1 && $3)?1:0; }
+;
+
+logical_or_expr
+: logical_and_expr { $$= $1; }
+| logical_or_expr PTOK_OR_OP logical_and_expr { $$= ($1 || $3)?1:0; }
+;
+
+conditional_expr
+: logical_or_expr { $$= $1; }
+| logical_or_expr PTOK_QUESTION expr PTOK_COLON conditional_expr { $$= ($1)?($3):($5); }
+;
+
+assignment_expr
+: conditional_expr { $$= $1; }
+/*| cast_expr assignment_operator assignment_expr*/
+/*| cast_expr PTOK_EQUAL assignment_expr*/
+| memory assignment_operator assignment_expr
+ {
+ t_mem org= $1.memory->read($1.address);
+ $$= $3;
+ switch ($2)
+ {
+ case PTOK_EQUAL:
+ $1.memory->write($1.address, $3);
+ break;
+ case PTOK_MUL_ASSIGN:
+ $1.memory->write($1.address, org *= $3);
+ break;
+ case PTOK_DIV_ASSIGN:
+ $1.memory->write($1.address, org /= $3);
+ break;
+ case PTOK_MOD_ASSIGN:
+ $1.memory->write($1.address, org %= $3);
+ break;
+ case PTOK_ADD_ASSIGN:
+ $1.memory->write($1.address, org += $3);
+ break;
+ case PTOK_SUB_ASSIGN:
+ $1.memory->write($1.address, org -= $3);
+ break;
+ case PTOK_LEFT_ASSIGN:
+ $1.memory->write($1.address, org <<= $3);
+ break;
+ case PTOK_RIGHT_ASSIGN:
+ $1.memory->write($1.address, org >>= $3);
+ break;
+ case PTOK_AND_ASSIGN:
+ $1.memory->write($1.address, org &= $3);
+ break;
+ case PTOK_XOR_ASSIGN:
+ $1.memory->write($1.address, org ^= $3);
+ break;
+ case PTOK_OR_ASSIGN:
+ $1.memory->write($1.address, org |= $3);
+ break;
+ }
+ $$= $1.memory->read($1.address);
+ }
+| bit PTOK_EQUAL assignment_expr
+ {
+ 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;
+ }
+ }
+;
+
+assignment_operator
+: PTOK_EQUAL { $$= PTOK_EQUAL; }
+| PTOK_MUL_ASSIGN { $$= PTOK_MUL_ASSIGN; }
+| PTOK_DIV_ASSIGN { $$= PTOK_DIV_ASSIGN; }
+| PTOK_MOD_ASSIGN { $$= PTOK_MOD_ASSIGN; }
+| PTOK_ADD_ASSIGN { $$= PTOK_ADD_ASSIGN; }
+| PTOK_SUB_ASSIGN { $$= PTOK_SUB_ASSIGN; }
+| PTOK_LEFT_ASSIGN { $$= PTOK_LEFT_ASSIGN; }
+| PTOK_RIGHT_ASSIGN { $$= PTOK_RIGHT_ASSIGN; }
+| PTOK_AND_ASSIGN { $$= PTOK_AND_ASSIGN; }
+| PTOK_XOR_ASSIGN { $$= PTOK_XOR_ASSIGN; }
+| PTOK_OR_ASSIGN { $$= PTOK_OR_ASSIGN; }
+;
+
+expr
+: assignment_expr { $$= $1; }
+| expr PTOK_COMMA assignment_expr { $$= $3; }
+;
+
+memory:
+ PTOK_MEMORY
+ | PTOK_MEMORY_OBJECT PTOK_LEFT_BRACKET expr PTOK_RIGHT_BRACKET
+ {
+ $$.memory= $1;
+ $$.address= $3;
+ }
+
+bit:
+ PTOK_BIT
+ | memory PTOK_DOT expr
+ {
+ $$.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);
+ }
+ ;
+
+%%
+
+static void
+yyerror (const char *msg)
+{
+ application->dd_cprintf ("error", "Parser error: %s\n", msg);
+}