Basic blocks now work.

This commit is contained in:
Jacob Signorovitch 2025-02-01 18:40:43 -05:00
parent 70393ef9ae
commit a5a86dc080
7 changed files with 70 additions and 42 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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" ]
} #}