ast for quadratic is correct

This commit is contained in:
vel 2024-11-15 02:53:17 -08:00
parent 8ee2bb29a7
commit 3479042b85
Signed by: velvox
GPG Key ID: 59D9762F674151DF
4 changed files with 62 additions and 25 deletions

View File

@ -34,6 +34,12 @@ struct stmt *stmt_create(stmt_t kind, struct decl *decl, struct expr *init_expr,
struct stmt *body, struct stmt *else_body, struct stmt *body, struct stmt *else_body,
struct stmt *next) { struct stmt *next) {
struct stmt *s = malloc(sizeof(*s)); struct stmt *s = malloc(sizeof(*s));
if (kind == STMT_COMPUTE) {
if (decl) {
printf("name: %s\n", decl->name->name);
}
}
s->kind = kind; s->kind = kind;
s->decl = decl; s->decl = decl;
s->init_expr = init_expr; s->init_expr = init_expr;
@ -137,6 +143,9 @@ void stmt_print(struct stmt *s) {
printf(" then\n"); printf(" then\n");
stmt_print(s->body); stmt_print(s->body);
printf("endif\n"); printf("endif\n");
if (!s->else_body) { printf("\n"); break;}
printf("else ");
stmt_print(s->else_body);
break; break;
case STMT_PRINT: case STMT_PRINT:
printf("print "); printf("print ");
@ -150,6 +159,11 @@ void stmt_print(struct stmt *s) {
case STMT_SECTION: case STMT_SECTION:
printf("section\n"); printf("section\n");
break; break;
case STMT_COMPUTE:
printf("compute ");
decl_print(s->decl);
printf(";\n");
break;
case STMT_END_EXECUTION: case STMT_END_EXECUTION:
printf("stop run\n"); printf("stop run\n");
break; break;
@ -175,15 +189,20 @@ void expr_print(struct expr *e) {
close = "]"; close = "]";
} else if (e->kind != EXPR_NAME && e->kind != EXPR_SUBSCRIPT && } else if (e->kind != EXPR_NAME && e->kind != EXPR_SUBSCRIPT &&
e->kind != EXPR_INTEGER_LITERAL && e->kind != EXPR_FLOAT_LITERAL && e->kind != EXPR_INTEGER_LITERAL && e->kind != EXPR_FLOAT_LITERAL &&
e->kind != EXPR_STRING_LITERAL) { e->kind != EXPR_STRING_LITERAL && e->kind != EXPR_CUSTOM_FUNCTION) {
printf("("); printf("(");
close = ")"; close = ")";
} else if (e->kind == EXPR_CUSTOM_FUNCTION) {
printf("FUNCTION ");
} }
expr_print(e->left); expr_print(e->left);
switch (e->kind) { switch (e->kind) {
case EXPR_NAME: case EXPR_NAME:
if (e->negative) {
printf("-");
}
printf("%s", e->name); printf("%s", e->name);
break; break;
case EXPR_ARRAY: case EXPR_ARRAY:
@ -234,6 +253,12 @@ void expr_print(struct expr *e) {
case EXPR_STRING_LITERAL: case EXPR_STRING_LITERAL:
printf("%s", e->string_literal); printf("%s", e->string_literal);
break; break;
case EXPR_EXPONENTIAL:
printf("**");
break;
case EXPR_CUSTOM_FUNCTION:
printf(" ");
break;
} }
expr_print(e->right); expr_print(e->right);
@ -265,6 +290,7 @@ void stmt_evaluate(struct stmt *s) {
break; break;
case STMT_PRINT: case STMT_PRINT:
stmt_evaluate_print(s->expr); stmt_evaluate_print(s->expr);
printf("\n");
break; break;
case STMT_BLOCK: case STMT_BLOCK:
stmt_evaluate(s->body); stmt_evaluate(s->body);

View File

@ -34,6 +34,8 @@ typedef enum {
EXPR_STRING_LITERAL, EXPR_STRING_LITERAL,
EXPR_SUBSCRIPT, EXPR_SUBSCRIPT,
EXPR_SUBTRACT, EXPR_SUBTRACT,
EXPR_NULL,
EXPR_CUSTOM_FUNCTION
} expr_t; } expr_t;
struct expr { struct expr {
@ -44,6 +46,7 @@ struct expr {
int integer_value; int integer_value;
float float_value; float float_value;
const char *string_literal; const char *string_literal;
int negative;
}; };
typedef enum { typedef enum {

View File

@ -95,8 +95,8 @@ extern struct stmt *parser_result = 0;
struct type *type; struct type *type;
} }
%type <stmt> statement_list statement section stop_run sect_data simple_stmt cbl_func_stmt cbl_function if_branch else_parts perform_stmt data_space %type <stmt> statement_list statement section stop_run sect_data simple_stmt cbl_func_stmt cbl_function if_branch else_parts else_branch perform_stmt data_space
%type <expr> mathmaticalexpr booleanexpr term op_parm container_expr type_expr op_parms math_op categry_contain category_value ident %type <expr> mathmaticalexpr booleanexpr term op_parm container_expr type_expr op_parms math_op categry_contain category_value ident ext_function
%type <decl> assignment_stmt simple_decl complex_decl data_declaration category_spec %type <decl> assignment_stmt simple_decl complex_decl data_declaration category_spec
%type <type> data_category complete_category data_clause %type <type> data_category complete_category data_clause
%% %%
@ -139,12 +139,10 @@ simple_stmt : cbl_func_stmt
| if_branch | if_branch
| perform_stmt | perform_stmt
; ;
cbl_func_stmt : cbl_function op_parms cbl_func_stmt : cbl_function ident assignment_stmt
{ $3->name = $2; $$= stmt_create($1->kind, $3, NULL, NULL, NULL, NULL, NULL, NULL);}
| cbl_function op_parms
{$$ = stmt_create($1->kind, NULL, NULL, $2, NULL, NULL, NULL, NULL);} {$$ = stmt_create($1->kind, NULL, NULL, $2, NULL, NULL, NULL, NULL);}
| cbl_function assignment_stmt
{$$ = stmt_create($1->kind, NULL, NULL, NULL, NULL, $2, NULL, NULL);}
| cbl_function op_parm assignment_stmt
{$$ = stmt_create($1->kind, NULL, NULL, $2, NULL, $3, NULL, NULL);}
; ;
assignment_stmt : TOKEN_EQUAL op_parms assignment_stmt : TOKEN_EQUAL op_parms
{$$ = decl_create(NULL, NULL, $2, NULL, NULL);} {$$ = decl_create(NULL, NULL, $2, NULL, NULL);}
@ -204,10 +202,12 @@ type_expr : ident
{$$ = expr_create_integer_literal(0);} {$$ = expr_create_integer_literal(0);}
// TODO: implment negative numbers // TODO: implment negative numbers
| TOKEN_SUB ident | TOKEN_SUB ident
{ $2->negative = 1; $$ = $2;}
| ext_function | ext_function
{$$ = $1;}
; ;
ext_function : TOKEN_KEYWORD_FUNCTION ident TOKEN_LEFT_PARENTHESIS ident TOKEN_RIGHT_PARENTHESIS ext_function : TOKEN_KEYWORD_FUNCTION ident TOKEN_LEFT_PARENTHESIS ident TOKEN_RIGHT_PARENTHESIS
{$$ = expr_create(EXPR_CUSTOM_FUNCTION, $2, $4);}
; ;
cbl_function : TOKEN_DISPLAY cbl_function : TOKEN_DISPLAY
{$$ = stmt_create(STMT_PRINT, NULL, NULL, NULL, NULL, NULL, NULL, NULL);} {$$ = stmt_create(STMT_PRINT, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
@ -217,14 +217,18 @@ cbl_function : TOKEN_DISPLAY
{$$ = stmt_create(STMT_COMPUTE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);} {$$ = stmt_create(STMT_COMPUTE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
; ;
if_branch : TOKEN_IF booleanexpr statement_list else_parts if_branch : TOKEN_IF booleanexpr statement_list else_parts
{$$ = stmt_create(STMT_IF, NULL, NULL, $2, $4, $3, NULL, NULL);} {$$ = stmt_create(STMT_IF, NULL, NULL, $2, NULL, $3, $4, NULL);}
; ;
else_parts : TOKEN_ELSE_IF booleanexpr statement_list else_parts : else_branch
{$$ = stmt_create(STMT_IF, NULL, NULL, $2, $3, NULL, NULL, NULL);} {$$ = $1;}
| else_parts else_branch
{$$ = $1; $1->else_body = $2;}
else_branch : TOKEN_ELSE_IF booleanexpr simple_stmt
{$$ = stmt_create(STMT_IF, NULL, NULL, $2, NULL, $3, NULL, NULL);}
| TOKEN_ELSE simple_stmt | TOKEN_ELSE simple_stmt
{$$ = stmt_create(STMT_IF, NULL, NULL, NULL, NULL, $2, NULL, NULL);} {$$ = stmt_create(STMT_IF, NULL, NULL, NULL, NULL, $2, NULL, NULL);}
| TOKEN_END_IF | TOKEN_END_IF
; {$$ = NULL;}
perform_stmt : TOKEN_PERFORM TOKEN_VARYING ident TOKEN_KEYWORD_FROM TOKEN_INTEGER TOKEN_KEYWORD_BY TOKEN_INTEGER TOKEN_UNTIL op_parms perform_stmt : TOKEN_PERFORM TOKEN_VARYING ident TOKEN_KEYWORD_FROM TOKEN_INTEGER TOKEN_KEYWORD_BY TOKEN_INTEGER TOKEN_UNTIL op_parms
| TOKEN_END_PERFORM | TOKEN_END_PERFORM
; ;
@ -257,6 +261,18 @@ data_clause : TOKEN_COMPUTATION_LEVEL_0
{$$ = type_create(TYPE_ALPHANUMERIC, NULL); $$->level = LEVEL_3;} {$$ = type_create(TYPE_ALPHANUMERIC, NULL); $$->level = LEVEL_3;}
| |
; ;
category_value : TOKEN_KEYWORD_VALUE TOKEN_INTEGER
{$$ = expr_create_integer_literal(atoi(yytext));}
| TOKEN_KEYWORD_OCCURS TOKEN_INTEGER
{$$ = expr_create_integer_literal(atoi(yytext));}
|
{$$ = expr_create(EXPR_NULL, NULL, NULL);}
;
category_spec : complete_category
{$$ = decl_create(NULL, $1, NULL, NULL, NULL);}
| complete_category data_clause category_value
{ $$ = decl_create(NULL, $1, $3, NULL, $2);}
;
//TODO: implement levels //TODO: implement levels
simple_decl : TOKEN_INTEGER ident TOKEN_DOT simple_decl : TOKEN_INTEGER ident TOKEN_DOT
{$$ = decl_create($2, NULL, NULL, NULL, NULL);} {$$ = decl_create($2, NULL, NULL, NULL, NULL);}
@ -264,17 +280,8 @@ simple_decl : TOKEN_INTEGER ident TOKEN_DOT
complex_decl : TOKEN_INTEGER ident TOKEN_PICTURE category_spec TOKEN_DOT complex_decl : TOKEN_INTEGER ident TOKEN_PICTURE category_spec TOKEN_DOT
{$$ = decl_create($2, $4->type, $4->value, NULL, NULL);} {$$ = decl_create($2, $4->type, $4->value, NULL, NULL);}
; ;
category_value : TOKEN_KEYWORD_VALUE TOKEN_INTEGER
{$$ = expr_create_integer_literal(atoi(yytext));}
| TOKEN_KEYWORD_OCCURS TOKEN_INTEGER
{$$ = expr_create_integer_literal(atoi(yytext));}
|
;
category_spec : complete_category
{$$ = decl_create(NULL, $1, NULL, NULL, NULL);}
| complete_category data_clause category_value
{ $$ = decl_create(NULL, $1, $3, NULL, $2);}
;
data_declaration: simple_decl data_declaration: simple_decl
{$$ = $1;} {$$ = $1;}
| complex_decl | complex_decl

View File

@ -30,4 +30,5 @@
DISPLAY "Root: " root1 DISPLAY "Root: " root1
ELSE ELSE
DISPLAY "The equation has no real roots." DISPLAY "The equation has no real roots."
END-IF
STOP RUN. STOP RUN.