You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
7.2 KiB
157 lines
7.2 KiB
%{
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "types.h"
|
|
#include "parser/parser.c"
|
|
#include "functions/functions.c"
|
|
#include "logic/logic.c"
|
|
#include "print/print.c"
|
|
#include "vars/vars.c"
|
|
|
|
int yylex(void);
|
|
void yyerror(char *);
|
|
extern int yylineno;
|
|
%}
|
|
|
|
%left '<' '>'
|
|
%left '+' '-'
|
|
%left '*' '/' '%'
|
|
|
|
%union {
|
|
char* str_ptr;
|
|
int int_num;
|
|
unsigned uint_num;
|
|
char byte_num;
|
|
double double_num;
|
|
float float_num;
|
|
struct node_info *node_ptr;
|
|
}
|
|
|
|
%token INCREASE
|
|
%token LESS_THAN_OR_EQUAL
|
|
%token GREATER_THAN_OR_EQUAL
|
|
%token DECREASE
|
|
%token PRINT_TOKEN
|
|
%token IF
|
|
%token END
|
|
%token KEYWORD_S
|
|
%token KEYWORD_I
|
|
%token KEYWORD_C
|
|
%token KEYWORD_D
|
|
%token QUOTE
|
|
%token ELSE
|
|
%token WHILE
|
|
%token DEF
|
|
%token CALL
|
|
%token POINT_VALUE
|
|
%token <str_ptr> MAIN_TOKEN
|
|
|
|
%token <int_num> INTEGER
|
|
%type <int_num> EXPR_I
|
|
|
|
%token <str_ptr> STRING VARNAME
|
|
%token <byte_num> EXPR_C
|
|
|
|
%token <double_num> DOUBLEVAR
|
|
%type <double_num> EXPR_D
|
|
|
|
%type <node_ptr> STMT PRINT VARIABLE FUNC STMT_LIST LOGIC MAIN ARGS
|
|
|
|
%%
|
|
PROGRAM:
|
|
MAIN { exec_stmt($1); exec_stmt(create_function_call("__main", NULL)); exit(0); }
|
|
|
|
|
;
|
|
|
|
MAIN:
|
|
MAIN_TOKEN ':' '{' STMT_LIST '}' ';' { $$ = create_function("__main", NULL, $4); }
|
|
| FUNC ';' MAIN { exec_stmt($1); $$ = $3; }
|
|
;
|
|
|
|
FUNC:
|
|
DEF VARNAME '[' ARGS ']' ':' '{' STMT_LIST '}' { $$ = create_function($2, $4, $8); }
|
|
| DEF VARNAME ':' '{' STMT_LIST '}' { $$ = create_function($2, NULL, $5); }
|
|
| CALL VARNAME { $$ = create_function_call($2, NULL); }
|
|
| CALL VARNAME '[' ARGS ']' { $$ = create_function_call($2, $4); }
|
|
;
|
|
|
|
ARGS:
|
|
VARNAME ',' ARGS { $$ = append_argument($1); }
|
|
| VARNAME { $$ = append_argument($1); }
|
|
;
|
|
|
|
STMT_LIST:
|
|
STMT ';' { $$ = create_compound_statement($1, _stmt_head_curser); }
|
|
| STMT_LIST STMT ';' { $$ = add_to_compound_statement($2, $1); }
|
|
;
|
|
|
|
STMT:
|
|
VARIABLE { $$ = $1; }
|
|
| LOGIC { $$ = $1; }
|
|
| FUNC { $$ = $1; }
|
|
| PRINT_TOKEN '[' PRINT ']' { $$ = $3; }
|
|
| '{' STMT_LIST '}' { $$ = $2; }
|
|
;
|
|
|
|
LOGIC:
|
|
IF '[' VARNAME ']' ':' '{' STMT_LIST '}' { $$ = create_logic_node(create_logic(IF_LOGIC, $7, $3)); }
|
|
| WHILE '[' VARNAME ']' ':' '{' STMT_LIST '}' { $$ = create_logic_node(create_logic(WHILE_LOGIC, $7, $3)); }
|
|
;
|
|
|
|
VARIABLE:
|
|
VARNAME '=' STRING { $$ = create_variable($1, (void *) $3, VAR_STRING);}
|
|
| VARNAME '=' EXPR_I { $$ = create_variable($1, alloc_value(&$3, VAR_INT), VAR_INT);}
|
|
| VARNAME '=' EXPR_D { $$ = create_variable($1, alloc_value(&$3, VAR_DOUBLE), VAR_DOUBLE);}
|
|
| VARNAME '=' EXPR_C { $$ = create_variable($1, alloc_value(&$3, VAR_BYTE), VAR_BYTE);}
|
|
| VARNAME '=' '{' STMT_LIST '}' { $$ = create_function($1, NULL, $4); }
|
|
| VARNAME '=' VARNAME { $$ = move_value($1, $3); }
|
|
;
|
|
|
|
EXPR_I:
|
|
INTEGER { $$ = $1; }
|
|
| EXPR_I '+' EXPR_I { $$ = $1 + $3; }
|
|
| EXPR_I '-' EXPR_I { $$ = $1 - $3; }
|
|
| EXPR_I '*' EXPR_I { $$ = $1 * $3; }
|
|
| EXPR_I '/' EXPR_I { if ($1 == 0 || $3 == 0) yyerror("cannot divide by zero!"); $$ = $1 / $3; }
|
|
| EXPR_I '%' EXPR_I { $$ = $1 % $3; }
|
|
| EXPR_I LESS_THAN_OR_EQUAL EXPR_I { $$ = $1 <= $3; }
|
|
| EXPR_I GREATER_THAN_OR_EQUAL EXPR_I { $$ = $1 >= $3; }
|
|
| EXPR_I '>' EXPR_I { $$ = $1 > $3; }
|
|
| EXPR_I '<' EXPR_I { $$ = $1 < $3; }
|
|
| INCREASE EXPR_I { $$ = $2 + 1; }
|
|
| EXPR_I INCREASE { $$ = $1 + 1; }
|
|
| DECREASE EXPR_I { $$ = $2 - 1; }
|
|
| EXPR_I DECREASE { $$ = $1 - 1; }
|
|
| '(' EXPR_I ')' { $$ = $2; }
|
|
;
|
|
|
|
EXPR_D:
|
|
DOUBLEVAR
|
|
| EXPR_D '+' EXPR_D { $$ = $1 + $3; }
|
|
| EXPR_D '-' EXPR_D { $$ = $1 - $3; }
|
|
| EXPR_D '*' EXPR_D { $$ = $1 * $3; }
|
|
| EXPR_D '/' EXPR_D { if ($1 == 0 || $3 == 0) yyerror("cannot divide by zero!"); $$ = $1 / $3; }
|
|
| EXPR_D LESS_THAN_OR_EQUAL EXPR_D { $$ = $1 <= $3; }
|
|
| EXPR_D GREATER_THAN_OR_EQUAL EXPR_D { $$ = $1 >= $3; }
|
|
| EXPR_D '>' EXPR_D { $$ = $1 > $3; }
|
|
| EXPR_D '<' EXPR_D { $$ = $1 < $3; }
|
|
| INCREASE EXPR_D { $$ = $2 + 1; }
|
|
| EXPR_D INCREASE { $$ = $1 + 1; }
|
|
| DECREASE EXPR_D { $$ = $2 - 1; }
|
|
| EXPR_D DECREASE { $$ = $1 - 1; }
|
|
| '(' EXPR_D ')' { $$ = $2; }
|
|
;
|
|
|
|
PRINT:
|
|
VARNAME { $$ = create_print_variable($1); }
|
|
| STRING { $$ = create_print_statement(VAR_STRING, $1); }
|
|
;
|
|
%%
|
|
|
|
void yyerror(char *s)
|
|
{
|
|
fprintf(stderr, "Error on line %d, %s\n", yylineno, s);
|
|
exit(0);
|
|
} |