Basic blocks now work.
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -30,7 +30,7 @@ UNITY_OBJ = $(TEST_BUILD_DIR)/unity.o | |||||||
| TEST_SRC_FILES = $(wildcard $(TEST_DIR)/*.c) | TEST_SRC_FILES = $(wildcard $(TEST_DIR)/*.c) | ||||||
| TEST_OBJ_FILES = $(patsubst $(TEST_DIR)/%.c, $(TEST_OBJ_DIR)/%.o, $(TEST_SRC_FILES)) | TEST_OBJ_FILES = $(patsubst $(TEST_DIR)/%.c, $(TEST_OBJ_DIR)/%.o, $(TEST_SRC_FILES)) | ||||||
| TEST_BIN_FILES = $(patsubst $(TEST_DIR)/%.c, $(TEST_BUILD_DIR)/%.out, $(TEST_SRC_FILES)) | TEST_BIN_FILES = $(patsubst $(TEST_DIR)/%.c, $(TEST_BUILD_DIR)/%.out, $(TEST_SRC_FILES)) | ||||||
| TEST_VAL_DIR = $(TEST_DIR)/validation | TEST_VAL_DIR = $(TEST_DIR)/val | ||||||
|  |  | ||||||
| RESETCOLOR = \033[0m | RESETCOLOR = \033[0m | ||||||
| WHITE = $(RESETCOLOR)\033[37m | WHITE = $(RESETCOLOR)\033[37m | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ void dlist_destroy(DList* dlist) { | |||||||
| void dlist_destroypsv(DList* dlist) { free(dlist); } | void dlist_destroypsv(DList* dlist) { free(dlist); } | ||||||
|  |  | ||||||
| // Check whether the buffer is overflowing and resize it if necessary. | // Check whether the buffer is overflowing and resize it if necessary. | ||||||
| void check_resz(DList* dlist, size_t ln) { | void dlist_check_resz(DList* dlist, size_t ln) { | ||||||
|     while (dlist->ln + ln + 1 > dlist->sz) { |     while (dlist->ln + ln + 1 > dlist->sz) { | ||||||
|         // Double the buffer size when overflown. |         // Double the buffer size when overflown. | ||||||
|         dlist->sz *= 2; |         dlist->sz *= 2; | ||||||
| @@ -34,7 +34,7 @@ void check_resz(DList* dlist, size_t ln) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void dlist_append(DList* dest, void* src) { | void dlist_append(DList* dest, void* src) { | ||||||
|     check_resz(dest, 1); |     dlist_check_resz(dest, 1); | ||||||
|  |  | ||||||
|     dest->buf[dest->ln] = src; |     dest->buf[dest->ln] = src; | ||||||
|     dest->ln += 1; |     dest->ln += 1; | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ void dstr_destroy(Dstr* dstr) { | |||||||
| void dstr_destroypsv(Dstr* dstr) { free(dstr); } | void dstr_destroypsv(Dstr* dstr) { free(dstr); } | ||||||
|  |  | ||||||
| // Check whether the buffer is overflowing and resize it if necessary. | // Check whether the buffer is overflowing and resize it if necessary. | ||||||
| void check_resz(Dstr* dstr, size_t ln) { | void dstr_check_resz(Dstr* dstr, size_t ln) { | ||||||
|     while (dstr->ln + ln + 1 > dstr->sz) { |     while (dstr->ln + ln + 1 > dstr->sz) { | ||||||
|         // Double the buffer size when overflown. |         // Double the buffer size when overflown. | ||||||
|         dstr->sz *= 2; |         dstr->sz *= 2; | ||||||
| @@ -36,7 +36,7 @@ void check_resz(Dstr* dstr, size_t ln) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void dstr_append(Dstr* dest, char* src, size_t ln) { | void dstr_append(Dstr* dest, char* src, size_t ln) { | ||||||
|     check_resz(dest, ln); |     dstr_check_resz(dest, ln); | ||||||
|  |  | ||||||
|     // Overwrites the \0 at the end of the string, keeps the null from the given |     // Overwrites the \0 at the end of the string, keeps the null from the given | ||||||
|     // string. |     // string. | ||||||
| @@ -45,7 +45,7 @@ void dstr_append(Dstr* dest, char* src, size_t ln) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void dstr_appendch(Dstr* dest, char ch) { | void dstr_appendch(Dstr* dest, char ch) { | ||||||
|     check_resz(dest, 1); |     dstr_check_resz(dest, 1); | ||||||
|  |  | ||||||
|     // Overwrites the preexisting null terminator, and adds one of its own. |     // Overwrites the preexisting null terminator, and adds one of its own. | ||||||
|     dest->buf[dest->ln] = ch; |     dest->buf[dest->ln] = ch; | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
|     #include <stdio.h> |     #include <stdio.h> | ||||||
|     #include "../../src/include/ast.h" |     #include "../../src/include/ast.h" | ||||||
|     #include "../../src/include/lexer.h" |     #include "../../src/include/lexer.h" | ||||||
|  |     #include "../../src/include/dlist.h" | ||||||
|  |  | ||||||
|     int yylex(void); |     int yylex(void); | ||||||
|     void yyerror(char const*); |     void yyerror(char const*); | ||||||
| @@ -12,6 +13,7 @@ | |||||||
|  |  | ||||||
| %code requires { | %code requires { | ||||||
|     #include "../../src/include/ast.h" |     #include "../../src/include/ast.h" | ||||||
|  |     #include "../../src/include/dlist.h" | ||||||
| } | } | ||||||
|  |  | ||||||
| %union { | %union { | ||||||
| @@ -19,36 +21,39 @@ | |||||||
|     char* strval; |     char* strval; | ||||||
|     AST* ast; |     AST* ast; | ||||||
|     ArgArr* argarr; |     ArgArr* argarr; | ||||||
|  |     DList* exps; | ||||||
| } | } | ||||||
|  |  | ||||||
| %define parse.error verbose | %define parse.error verbose | ||||||
|  |  | ||||||
| %token BLOCKS | %token BLOCKS // Block start {. | ||||||
| %token BLOCKE | %token BLOCKE // Block end }. | ||||||
|  |  | ||||||
| %token GROUPS | %token GROUPS // Group start (. | ||||||
| %token GROUPE | %token GROUPE // Group end ). | ||||||
| %token SEP | %token SEP // Seperator ,. | ||||||
|  |  | ||||||
| %token EXPSEP | %token EXPSEP // Expression seperator ;. | ||||||
|  |  | ||||||
| %token<strval> WORD | %token<strval> WORD // Word, i.e. keyword. | ||||||
| %token<fval> NUM | %token<fval> NUM // Number. | ||||||
|  |  | ||||||
| %token SUB | %token SUB // Subtract -. | ||||||
| %token PLUS | %token ADD // Addition *.  | ||||||
| %token MULT | %token MUL // Multiplication *. | ||||||
| %token DIV | %token DIV // Division /. | ||||||
|  |  | ||||||
| %token NL | %token NL // Newline. | ||||||
|  |  | ||||||
| %left PLUS SUB | %left ADD SUB | ||||||
| %left MULT DIV | %left MUL DIV | ||||||
| %precedence NEG | %precedence NEG | ||||||
|  |  | ||||||
| %type<ast> exp; | %type<ast> exp; | ||||||
| %type<argarr> arg; | %type<argarr> arg; | ||||||
| %type<argarr> argstart; | %type<argarr> argstart; | ||||||
|  | %type<exps> blockstart; | ||||||
|  | %type<exps> block; | ||||||
|  |  | ||||||
| %% | %% | ||||||
|  |  | ||||||
| @@ -58,7 +63,6 @@ input: | |||||||
|     | input EXPSEP exp { root = $3; } |     | input EXPSEP exp { root = $3; } | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
|  |  | ||||||
| argstart: | argstart: | ||||||
|     exp { |     exp { | ||||||
|         ArgArr* argarr = argarr_init(); |         ArgArr* argarr = argarr_init(); | ||||||
| @@ -75,9 +79,32 @@ arg: | |||||||
|     } |     } | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
|  | blockstart: | ||||||
|  |     exp { | ||||||
|  |         DList* exps = dlist_init(); // List of expressions. | ||||||
|  |         dlist_append(exps, $1); | ||||||
|  |         $$ = exps; | ||||||
|  |     } | ||||||
|  |     ; | ||||||
|  |  | ||||||
|  | block: | ||||||
|  |      blockstart { $$ = $1; } | ||||||
|  |      | block EXPSEP exp { | ||||||
|  |         dlist_append($1, $3); | ||||||
|  |         $$ = $1; | ||||||
|  |     } | ||||||
|  |     ; | ||||||
|  |  | ||||||
| exp: | exp: | ||||||
|     NUM { $$ = ast_init(AST_TYPE_NUM, ast_num_data_init($1)); } |     NUM { $$ = ast_init(AST_TYPE_NUM, ast_num_data_init($1)); } | ||||||
|  |  | ||||||
|  |     | BLOCKS exp BLOCKE { $$ = $2; } | ||||||
|  |  | ||||||
|  |     | BLOCKS block BLOCKE { | ||||||
|  |         size_t i = $2->ln - 1; | ||||||
|  |         $$ = $2->buf[i]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     | SUB exp { |     | SUB exp { | ||||||
|         AST** argv = calloc(2, sizeof(AST*)); |         AST** argv = calloc(2, sizeof(AST*)); | ||||||
|         argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(-1)); |         argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(-1)); | ||||||
| @@ -87,7 +114,7 @@ exp: | |||||||
|         $$ = ast_init(AST_TYPE_CALL, ast_call_data_init(to, 2, argv)); |         $$ = ast_init(AST_TYPE_CALL, ast_call_data_init(to, 2, argv)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     | LGROUP exp RGROUP { $$ = $2; } |     | GROUPS exp GROUPE { $$ = $2; } | ||||||
|  |  | ||||||
|     // Variable reference. |     // Variable reference. | ||||||
|     | WORD { |     | WORD { | ||||||
| @@ -101,7 +128,7 @@ exp: | |||||||
|         $$ = ast_init(AST_TYPE_CALL, ast_call_data_init($1, argc, argv)); |         $$ = ast_init(AST_TYPE_CALL, ast_call_data_init($1, argc, argv)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     | exp PLUS exp { |     | exp ADD exp { | ||||||
|         AST** argv = calloc(2, sizeof(AST*)); |         AST** argv = calloc(2, sizeof(AST*)); | ||||||
|         argv[0] = $1; |         argv[0] = $1; | ||||||
|         argv[1] = $3; |         argv[1] = $3; | ||||||
| @@ -119,7 +146,7 @@ exp: | |||||||
|         $$ = ast_init(AST_TYPE_CALL, ast_call_data_init(to, 2, argv)); |         $$ = ast_init(AST_TYPE_CALL, ast_call_data_init(to, 2, argv)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     | exp MULT exp { |     | exp MUL exp { | ||||||
|         AST** argv = calloc(2, sizeof(AST*)); |         AST** argv = calloc(2, sizeof(AST*)); | ||||||
|         argv[0] = $1; |         argv[0] = $1; | ||||||
|         argv[1] = $3; |         argv[1] = $3; | ||||||
|   | |||||||
| @@ -104,13 +104,13 @@ int yylex() { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     switch (c) { |     switch (c) { | ||||||
|         case '+':  return PLUS; |         case '+':  return ADD; | ||||||
|         case '\n': return NL; |         case '\n': return NL; | ||||||
|         case '-':  return SUB; |         case '-':  return SUB; | ||||||
|         case '*':  return MULT; |         case '*':  return MUL; | ||||||
|         case '/':  return DIV; |         case '/':  return DIV; | ||||||
|         case '(':  return LGROUP; |         case '(':  return GROUPS; | ||||||
|         case ')':  return RGROUP; |         case ')':  return GROUPE; | ||||||
|         case ',':  return SEP; |         case ',':  return SEP; | ||||||
|         case ';': return EXPSEP; |         case ';': return EXPSEP; | ||||||
|         case '{': return BLOCKS; |         case '{': return BLOCKS; | ||||||
|   | |||||||
| @@ -52,7 +52,7 @@ void test_ast_vref() { | |||||||
|  |  | ||||||
| int main() { | int main() { | ||||||
|     UNITY_BEGIN(); |     UNITY_BEGIN(); | ||||||
|     //RUN_TEST(test_ast_num); |     RUN_TEST(test_ast_num); | ||||||
|     //RUN_TEST(test_ast_call); |     //RUN_TEST(test_ast_call); | ||||||
|     //RUN_TEST(test_ast_vref); |     //RUN_TEST(test_ast_vref); | ||||||
|     return UNITY_END(); |     return UNITY_END(); | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ bin() { ./scl.out $1 | tail -n1; } | |||||||
|     [ "$output" = "= 2.000000" ] |     [ "$output" = "= 2.000000" ] | ||||||
| 
 | 
 | ||||||
|     run bin "-1+1" |     run bin "-1+1" | ||||||
|  |     echo $output | ||||||
|     [ "$output" = "= 0.000000" ] |     [ "$output" = "= 0.000000" ] | ||||||
| 
 | 
 | ||||||
|     run bin "1+-1" |     run bin "1+-1" | ||||||
| @@ -88,15 +89,15 @@ bin() { ./scl.out $1 | tail -n1; } | |||||||
|     [ "$output" = "= 2.000000" ] |     [ "$output" = "= 2.000000" ] | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @test "variable definition" { | #@test "variable definition" { | ||||||
|     run bin "x = 1" | #    run bin "x = 1" | ||||||
|     [ "$output" = "= 1.000000" ] | #    [ "$output" = "= 1.000000" ] | ||||||
| 
 | # | ||||||
|     run bin "x = 1; x + 1" | #    run bin "x = 1; x + 1" | ||||||
|     [ "$output" = "= 2.000000" ] | #    [ "$output" = "= 2.000000" ] | ||||||
| } | #} | ||||||
| 
 | # | ||||||
| @test "function definition" { | #@test "function definition" { | ||||||
|     run bin "f(n)=2*n; f(2)" | #    run bin "f(n)=2*n; f(2)" | ||||||
|     [ "$output" = "= 4.000000" ] | #    [ "$output" = "= 4.000000" ] | ||||||
| } | #} | ||||||
		Reference in New Issue
	
	Block a user