C99 compat + tests

This commit is contained in:
attilavs2 2025-03-16 15:19:28 +01:00
parent 117839fa05
commit f1670722c2
6 changed files with 56 additions and 18 deletions

View file

@ -3,7 +3,7 @@
OUTNAME = flisp
CFLAGS = -O0 -Wall -Wextra -g -pipe -Wno-cast-function-type
CFLAGS = -std=c99 -O0 -Wall -Wextra -g -pipe -Wno-cast-function-type
CC = gcc

View file

@ -2,7 +2,7 @@
#pragma once
#define FL_EPSILON (1e-6f)
#define FL_EPSILON (1e-7f)
enum OpTypes {
OP_add = 0,
@ -132,9 +132,9 @@ typedef struct {
} FnSig;
#ifndef win
_Static_assert(sizeof(Value) == 8);
_Static_assert(sizeof(Value) == 8, "Value isn't the right size");
#endif
_Static_assert(sizeof(Tag) <= sizeof(i32));
_Static_assert(sizeof(Tag) <= sizeof(i32), "Tag is too large for tomfoolery");
static inline FnSig *get_fnsig(Value *x){
u64 rval = *((u64*)x);

View file

@ -88,4 +88,4 @@ typedef struct {
} ASTStack;
_Static_assert((int)BI_var >= ST__end);
_Static_assert((int)BI_var >= ST__end, "Overlap between BI and ST enums");

View file

@ -122,6 +122,7 @@ Value write(Value a);
void print_ast1(Statement *base, i32 indent){
i32 close_parent = 1;
printf("# ");
for(int i = 0; i < indent; i++)
printf(" ");
switch(base->type){
@ -147,7 +148,7 @@ void print_ast1(Statement *base, i32 indent){
printf("(use<%d>\n", base->var_id);
break;
case BI_var:
printf("(var<%d>\n", base->var_id);
printf("(var<%d>:<%d>\n", base->var_id, base->var_type.type);
break;
case BI_if:
printf("(if\n");
@ -172,6 +173,7 @@ void print_ast1(Statement *base, i32 indent){
print_ast1(base->children[i], indent+1);
if(close_parent){
printf("# ");
for(int i = 0; i < indent; i++)
printf(" ");
printf(")\n");
@ -180,7 +182,7 @@ void print_ast1(Statement *base, i32 indent){
void print_ast(Statement *base){
#if LOG
printf("AST :\n");
printf("# AST :\n");
print_ast1(base, 0);
#endif
}

View file

@ -58,6 +58,7 @@ Statement *make_iconst(i32 val){
Statement *stat = &stack->statements[stack->curr_statement++];
stat->type = ST_Const;
stat->cons = (Value){{.v4B = {val}},{.is_array = 0, .type = T_int}};
stat->is_const = 1;
stat->child_n = 0;
return stat;
}
@ -66,6 +67,7 @@ Statement *make_fconst(float val){
Statement *stat = &stack->statements[stack->curr_statement++];
stat->type = ST_Const;
stat->cons = (Value){{.v4B = {.vfl=val}},{.is_array=0,.type=T_float}};
stat->is_const = 1;
stat->child_n = 0;
return stat;
}
@ -79,13 +81,13 @@ Statement *declare(i32 type, Tag vtype, char *name, Statement *assign){
#if LOG
printf("declare : %d\n", vtype.type);
#endif
char *name2 = strndup(name, len);
name[len] = '\0';
Statement *stat = &stack->statements[stack->curr_statement++];
stat->type = type;
if(hashmap_get(&stack->symbol_map, name2)){
if(hashmap_get(&stack->symbol_map, name)){
yyerror("Redeclaring existing identifier");
}
MapItem *ret = hashmap_insert(&stack->symbol_map, name2);
MapItem *ret = hashmap_insert(&stack->symbol_map, name);
ret->type = *((i16*)&vtype);
#if LOG
printf("id : %d\n", ret->id);
@ -147,12 +149,11 @@ Statement *make_operation(i32 type, Tag vtype, char *name, i32 nparam, ...){
if(!type || type == ST_Call){
i32 len = strcspn(name, " \t\n()");
char *name2 = strndup(name, len);
name[len] = '\0';
#if LOG
printf("name : \"%s\" ; name2 : \"%s\"\n",name,name2);
printf("name : \"%s\"\n",name);
#endif
MapItem *ret = hashmap_get(&stack->symbol_map, name2);
free(name2);
MapItem *ret = hashmap_get(&stack->symbol_map, name);
if(!ret)
yyerror("Undefined identifer");
#if LOG

View file

@ -34,10 +34,10 @@ int t_hashmap_remove(){
int err = 0;
hashmap_remove(&t_hmap, "test");
MapItem *ret = hashmap_get(&t_hmap, "test");
err += ret;
err += !!ret;
MapItem *ret2 = hashmap_insert(&t_hmap, "very_verbose_function_i_guess");
hashmap_remove_id(&t_hmap, ret2->id);
err += hashmap_get(&t_hmap, "very_verbose_function_i_guess");
err += !!hashmap_get(&t_hmap, "very_verbose_function_i_guess");
return err;
}
@ -60,6 +60,35 @@ int t_make_stack(){
return make_stack();
}
int t_make_iconst(){
int err = 0;
Statement *st = NULL;
st = make_iconst(69);
if(!st)
return 1;
err += st->type != ST_Const || !st->is_const || st->child_n;
err += st->cons.v4B.value != 69 || st->cons.tag.type != T_int;
err += st->cons.tag.is_array;
return err;
}
int t_make_fconst(){
int err = 0;
Statement *st = NULL;
st = make_fconst(0.420);
if(!st)
return 1;
err += st->type != ST_Const || !st->is_const || st->child_n;
err += st->cons.v4B.vfl != 0.420f || st->cons.tag.type != T_float;
err += st->cons.tag.is_array;
return err;
}
// TODO
int t_make_strconst(){
return 0;
}
int t_free_stack(){
free_stack();
return 0;
@ -72,6 +101,9 @@ test_fun_t *tests[] = {
t_free_hashmap,
t_get_type,
t_make_stack,
t_make_iconst,
t_make_fconst,
t_make_strconst,
t_free_stack
};
@ -83,6 +115,9 @@ char *names[] = {
"free_hashmap",
"get_type",
"make_stack",
"make_iconst",
"make_fconst",
"make_strconst (TODO)",
"free_stack"
};
@ -92,11 +127,11 @@ void do_tests(){
assert(tlen == sizeof(names)/sizeof(void*)); // If forgot to name a test
for(int i = 0; i < tlen; i++){
if(tests[i]()){
printf("Test \"%s\" : \x1B[31m[FAILED]\x1B[0m\n", names[i]);
printf("\x1B[31m[FAILED]\x1B[0m test \"%s\"\n", names[i]);
exit(1);
}
else{
printf("Test \"%s\" : \x1B[32m[PASSED]\x1B[0m\n", names[i]);
printf("\x1B[32m[PASSED]\x1B[0m test \"%s\"\n", names[i]);
}
}
}