11 #include "dynstrings.h"
15 void yyerror (char *err
,...
);
16 void yyerror_loc
(YYLTYPE *yylloc,char *err
,...
);
19 extern
FILE *c_output
;
20 extern TreeNode
*root
;
28 %token FN NEWLINE SHL SHR EQU
29 %token
<node
> IF WHILE RETURN TRUE FALSE DECNUM HEXNUM STRNUM ID
31 %type
<node
> blob get_length get_element expr assign call_args callfn line startline codeblock function func_args init
45 init: /* EPSILON */ { $$
= NULL
; }
46 | NEWLINE init
{ $$
= NULL
; }
47 | function init
{ $$
= node_new
(); $$
->id
= NODE_ROOT
; node_bottom
($$
, $1); node_next
(root
, $$
); }
50 function: FN ID
'(' func_args
')' codeblock
{ $$
= node_new
(); $$
->id
= NODE_FUNCTION
; node_next
($$
, $4); node_next
($$
, $2); node_bottom
($$
, $6); }
51 | FN ID
'(' ')' codeblock
{ $$
= node_new
(); $$
->id
= NODE_FUNCTION
; node_next
($$
, $2); node_bottom
($$
, $5); }
54 func_args: ID
{ $$
= node_new
(); $$
->id
= NODE_FUNC_ARGS
; node_bottom
($$
, $1); }
55 | ID
',' func_args
{ $$
= node_new
(); $$
->id
= NODE_FUNC_ARGS
; node_next
($$
, $3); node_bottom
($$
, $1); }
58 codeblock: '{' NEWLINE startline
'}' NEWLINE
{ $$
= node_new
(); $$
->id
= NODE_CODEBLOCK
; node_bottom
($$
, $3); }
59 | NEWLINE
'{' NEWLINE startline
'}' NEWLINE
{ $$
= node_new
(); $$
->id
= NODE_CODEBLOCK
; node_bottom
($$
, $4); }
62 startline: /* EPSILON */ { $$
= node_new
(); $$
->id
= NODE_LINE
; node_bottom
($$
, node_new
()); }
63 | NEWLINE startline
{ $$
= $2; }
64 | line startline
{ $$
= node_new
(); $$
->id
= NODE_LINE
; node_next
($$
, $2); node_bottom
($$
, $1); }
67 line: RETURN expr NEWLINE
{ $$
= $1; node_bottom
($$
, $2); }
68 | assign NEWLINE
{ $$
= $1; }
69 | callfn NEWLINE
{ $$
= node_new
(); $$
->id
= NODE_VOID_RETURN
; node_bottom
($$
, $1); }
70 | IF
'(' expr
')' codeblock
{ $$
= $1; node_next
($$
, $3); node_bottom
($$
, $5); }
71 | WHILE
'(' expr
')' codeblock
{ $$
= $1; node_next
($$
, $3); node_bottom
($$
, $5); }
83 callfn: ID
'(' call_args
')' { $$
= node_new
(); $$
->id
= NODE_CALLFN
; node_bottom
($$
, $3); node_bottom
($$
, $1); }
84 | ID
'(' ')' { $$
= node_new
(); $$
->id
= NODE_CALLFN
; node_bottom
($$
, $1); }
87 call_args: expr
{ $$
= node_new
(); $$
->id
= NODE_CALL_ARGS
; node_bottom
($$
, $1); }
88 | expr
',' call_args
{ $$
= node_new
(); $$
->id
= NODE_CALL_ARGS
; node_bottom
($$
, $1); node_next
($$
, $3); }
92 | expr
'+' expr
{ $$
= node_new
(); $$
->id
= NODE_ARIT_BINARY
; node_set
($$
, strdup
("Add")); node_bottom
($$
, $1); node_bottom
($$
, $3); }
93 | expr
'-' expr
{ $$
= node_new
(); $$
->id
= NODE_ARIT_BINARY
; node_set
($$
, strdup
("Subtract")); node_bottom
($$
, $1); node_bottom
($$
, $3); }
94 | expr
'*' expr
{ $$
= node_new
(); $$
->id
= NODE_ARIT_BINARY
; node_set
($$
, strdup
("Multiply")); node_bottom
($$
, $1); node_bottom
($$
, $3); }
95 | expr
'/' expr
{ $$
= node_new
(); $$
->id
= NODE_ARIT_BINARY
; node_set
($$
, strdup
("Divide")); node_bottom
($$
, $1); node_bottom
($$
, $3); }
96 | expr
'%' expr
{ $$
= node_new
(); $$
->id
= NODE_ARIT_BINARY
; node_set
($$
, strdup
("Modulo")); node_bottom
($$
, $1); node_bottom
($$
, $3); }
97 | expr
'^' expr
{ $$
= node_new
(); $$
->id
= NODE_ARIT_BINARY
; node_set
($$
, strdup
("Xor")); node_bottom
($$
, $1); node_bottom
($$
, $3); }
98 | expr
'&' expr
{ $$
= node_new
(); $$
->id
= NODE_ARIT_BINARY
; node_set
($$
, strdup
("And")); node_bottom
($$
, $1); node_bottom
($$
, $3); }
99 | expr
'|' expr
{ $$
= node_new
(); $$
->id
= NODE_ARIT_BINARY
; node_set
($$
, strdup
("Or")); node_bottom
($$
, $1); node_bottom
($$
, $3); }
100 |
'!' expr %prec NEG
{ $$
= node_new
(); $$
->id
= NODE_ARIT_UNARY
; node_set
($$
, strdup
("Not")); node_bottom
($$
, $2); }
101 |
'-' expr %prec NEG
{ $$
= node_new
(); $$
->id
= NODE_ARIT_UNARY
; node_set
($$
, strdup
("Negate")); node_bottom
($$
, $2); }
102 | expr SHL expr
{ $$
= node_new
(); $$
->id
= NODE_ARIT_BINARY
; node_set
($$
, strdup
("ShiftLeft")); node_bottom
($$
, $1); node_bottom
($$
, $3); }
103 | expr SHR expr
{ $$
= node_new
(); $$
->id
= NODE_ARIT_BINARY
; node_set
($$
, strdup
("ShiftRight")); node_bottom
($$
, $1); node_bottom
($$
, $3); }
104 | expr
'>' expr
{ $$
= node_new
(); $$
->id
= NODE_ARIT_BINARY
; node_set
($$
, strdup
("Greater")); node_bottom
($$
, $1); node_bottom
($$
, $3); }
105 | expr
'<' expr
{ $$
= node_new
(); $$
->id
= NODE_ARIT_BINARY
; node_set
($$
, strdup
("Greater")); node_bottom
($$
, $3); node_bottom
($$
, $1); }
106 | expr EQU expr
{ $$
= node_new
(); $$
->id
= NODE_ARIT_BINARY
; node_set
($$
, strdup
("Equals")); node_bottom
($$
, $1); node_bottom
($$
, $3); }
108 |
'$' get_length
{ $$
= node_new
(); $$
->id
= NODE_GET_LENGTH
; node_bottom
($$
, $2); }
109 |
'(' expr
')' %prec PARS
{ $$
= $2; }
112 get_length: '$' get_length
{ $$
= node_new
(); $$
->id
= NODE_GET_LENGTH
; node_bottom
($$
, $2); }
113 |
'(' expr
')' { $$
= $2; }
117 get_element: get_length
'[' expr
']' { $$
= node_new
(); $$
->id
= NODE_GET_ELEMENT
; node_bottom
($$
, $1); node_bottom
($$
, $3); }
118 | get_element
'[' expr
']' { $$
= node_new
(); $$
->id
= NODE_GET_ELEMENT
; node_bottom
($$
, $1); node_bottom
($$
, $3); }
121 assign: ID
'=' expr
{ $$
= node_new
(); $$
->id
= NODE_SET_VARIABLE
; node_bottom
($$
, $1); node_bottom
($$
, $3); }
122 | ID
'[' expr
']' '=' expr
{ $$
= node_new
(); $$
->id
= NODE_SET_ELEMENT
; node_bottom
($$
, $1); node_bottom
($$
, $3); node_bottom
($$
, $6); }
123 |
'$' ID
'=' expr
{ $$
= node_new
(); $$
->id
= NODE_SET_LENGTH
; node_bottom
($$
, $2); node_bottom
($$
, $4); }
128 void yyerror(char *err
, ...
) {
131 core_error
(str_printf
("Error (at position %d:%d-%d:%d) : ", yylloc.first_line
, yylloc.first_column
, yylloc.last_line
, yylloc.last_column
));
132 core_error
(str_vprintf
(err
, list
));
133 core_error
(strdup
("\n"));
137 void yyerrorloc
(YYLTYPE *yylloc,char *err
, ...
) {
140 core_error
(str_printf
("Error (at position %d:%d-%d:%d) : ", yylloc->first_line
, yylloc->first_column
, yylloc->last_line
, yylloc->last_column
));
141 core_error
(str_vprintf
(err
, list
));
142 core_error
(strdup
("\n"));
146 int main
(int argc
, char **argv
) {
150 input
= fopen
(argv
[1], "r");
152 fprintf
(stderr
, "Error opening file \"%s\"\n", argv
[1]);
161 yylloc.first_line
= yylloc.last_line
= 1;
162 yylloc.first_column
= yylloc.last_column
= 1;