Compare commits
7 Commits
5ecdf2d89a
...
47a3143752
Author | SHA1 | Date | |
---|---|---|---|
47a3143752 | |||
4fb73b3c6f | |||
e5c58d5fc5 | |||
5d81054cf6 | |||
66c518fe43 | |||
a5a86dc080 | |||
70393ef9ae |
2
Makefile
2
Makefile
@ -30,7 +30,7 @@ UNITY_OBJ = $(TEST_BUILD_DIR)/unity.o
|
||||
TEST_SRC_FILES = $(wildcard $(TEST_DIR)/*.c)
|
||||
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_VAL_DIR = $(TEST_DIR)/validation
|
||||
TEST_VAL_DIR = $(TEST_DIR)/val
|
||||
|
||||
RESETCOLOR = \033[0m
|
||||
WHITE = $(RESETCOLOR)\033[37m
|
||||
|
3
examples/function.scl
Normal file
3
examples/function.scl
Normal file
@ -0,0 +1,3 @@
|
||||
f(n) = 2 * n
|
||||
|
||||
f(5)
|
61
src/ast.c
61
src/ast.c
@ -9,7 +9,9 @@ extern AST* root;
|
||||
static char* asttype_names[] = {
|
||||
[AST_TYPE_CALL] = "FUNC CALL",
|
||||
[AST_TYPE_NUM] = "NUMBER",
|
||||
[AST_TYPE_VREF] = "VAR REFERENCE"
|
||||
[AST_TYPE_VREF] = "VAR REFERENCE",
|
||||
[AST_TYPE_VDEF] = "VAR DEFINITION",
|
||||
[AST_TYPE_BLOCK] = "BLOCK",
|
||||
};
|
||||
|
||||
AST* ast_init(ASTType type, void* data) {
|
||||
@ -28,6 +30,7 @@ void ast_destroy(AST* ast) {
|
||||
case AST_TYPE_NUM: ast_num_data_destroy(ast->data); break;
|
||||
case AST_TYPE_CALL: ast_call_data_destroy(ast->data); break;
|
||||
case AST_TYPE_VREF: ast_vref_data_destroy(ast->data); break;
|
||||
case AST_TYPE_VDEF: ast_vdef_data_destroy(ast->data); break;
|
||||
default:
|
||||
log_dbgf("Unknown ast type %d (max: %d)", ast->type, AST_TYPE_MAX);
|
||||
}
|
||||
@ -49,6 +52,7 @@ void ast_print_i(AST* ast, int i) {
|
||||
break;
|
||||
case AST_TYPE_CALL: ast_call_print(ast->data, i + 2); break;
|
||||
case AST_TYPE_VREF: ast_vref_print(ast->data, i + 2); break;
|
||||
case AST_TYPE_VDEF: ast_vdef_print(ast->data, i + 2); break;
|
||||
default: exit(1);
|
||||
}
|
||||
INDENT_FIELD_NONL_END;
|
||||
@ -104,6 +108,33 @@ void ast_call_print(ASTCallData* data, int i) {
|
||||
INDENT_END;
|
||||
}
|
||||
|
||||
ASTVDefData* ast_vdef_data_init(char* name, AST* val) {
|
||||
talloc(ASTVDefData, vdef);
|
||||
|
||||
vdef->name = name;
|
||||
vdef->val = val;
|
||||
|
||||
return vdef;
|
||||
}
|
||||
|
||||
void ast_vdef_data_destroy(ASTVDefData* vdef) {
|
||||
ast_destroy(vdef->val);
|
||||
free(vdef->name);
|
||||
free(vdef);
|
||||
}
|
||||
|
||||
void ast_vdef_print(ASTVDefData* vdef, int depth) {
|
||||
INDENT_BEGIN(depth);
|
||||
|
||||
INDENT_TITLE("ASTVDefData", vdef);
|
||||
INDENT_FIELD("name", "%s", vdef->name);
|
||||
INDENT_FIELD_EXT_NONL_START("val");
|
||||
ast_print_i(vdef->val, depth + 2); // 2 because already indented.
|
||||
INDENT_FIELD_NONL_END;
|
||||
|
||||
INDENT_END;
|
||||
}
|
||||
|
||||
ASTVrefData* ast_vref_data_init(char* to) {
|
||||
talloc(ASTVrefData, vref);
|
||||
|
||||
@ -125,3 +156,31 @@ void ast_vref_print(ASTVrefData* data, int i) {
|
||||
|
||||
INDENT_END;
|
||||
}
|
||||
|
||||
ASTBlockData* ast_block_data_init(AST** inside, size_t ln) {
|
||||
ASTBlockData* block = malloc(sizeof(ASTBlockData));
|
||||
|
||||
block->inside = calloc(ln, sizeof(AST));
|
||||
block->ln = ln;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
void ast_block_data_destroy(ASTBlockData* block) {
|
||||
for (size_t i = 0; i < block->ln; i++) {
|
||||
ast_destroy(block->inside[i]);
|
||||
}
|
||||
|
||||
free(block->inside);
|
||||
free(block);
|
||||
}
|
||||
|
||||
void ast_block_data_print(ASTBlockData* data, int depth) {
|
||||
INDENT_BEGIN(depth);
|
||||
|
||||
INDENT_TITLE("BLOCK", data);
|
||||
INDENT_FIELD("ln", "%ld", data->ln);
|
||||
INDENT_FIELD_LIST("inside", data->inside, data->ln, ast_print_i);
|
||||
|
||||
INDENT_END;
|
||||
}
|
||||
|
41
src/dlist.c
Normal file
41
src/dlist.c
Normal file
@ -0,0 +1,41 @@
|
||||
#include "include/dlist.h"
|
||||
#include "include/util.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
DList* dlist_init(void) {
|
||||
DList* dlist = malloc(sizeof(DList));
|
||||
|
||||
dlist->sz = DLIST_INITSZ;
|
||||
dlist->buf = malloc(DLIST_INITSZ);
|
||||
dlist->ln = 0;
|
||||
|
||||
return dlist;
|
||||
}
|
||||
|
||||
void dlist_destroy(DList* dlist) {
|
||||
free(dlist->buf);
|
||||
free(dlist);
|
||||
}
|
||||
|
||||
void dlist_destroypsv(DList* dlist) { free(dlist); }
|
||||
|
||||
// Check whether the buffer is overflowing and resize it if necessary.
|
||||
void dlist_check_resz(DList* dlist, size_t ln) {
|
||||
while (dlist->ln + ln + 1 > dlist->sz) {
|
||||
// Double the buffer size when overflown.
|
||||
dlist->sz *= 2;
|
||||
dlist->buf = realloc(dlist->buf, dlist->sz);
|
||||
log_dbgf(
|
||||
"dlist @ %p doubled from %ld to %ld", dlist, dlist->sz / 2, dlist->sz
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void dlist_append(DList* dest, void* src) {
|
||||
dlist_check_resz(dest, 1);
|
||||
|
||||
dest->buf[dest->ln] = src;
|
||||
dest->ln += 1;
|
||||
}
|
@ -24,7 +24,7 @@ void dstr_destroy(Dstr* dstr) {
|
||||
void dstr_destroypsv(Dstr* dstr) { free(dstr); }
|
||||
|
||||
// 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) {
|
||||
// Double the buffer size when overflown.
|
||||
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) {
|
||||
check_resz(dest, ln);
|
||||
dstr_check_resz(dest, ln);
|
||||
|
||||
// Overwrites the \0 at the end of the string, keeps the null from the given
|
||||
// string.
|
||||
@ -45,7 +45,7 @@ void dstr_append(Dstr* dest, char* src, size_t ln) {
|
||||
}
|
||||
|
||||
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.
|
||||
dest->buf[dest->ln] = ch;
|
||||
|
@ -14,6 +14,7 @@ ASTNumData exec_exp(AST* ast) {
|
||||
case AST_TYPE_CALL: return exec_call(ast);
|
||||
case AST_TYPE_NUM: return *(ASTNumData*)ast->data;
|
||||
case AST_TYPE_VREF: return exec_vref(ast);
|
||||
case AST_TYPE_VDEF: return exec_vdef(ast);
|
||||
default: printf("what\n");
|
||||
exit(1);
|
||||
}
|
||||
@ -68,6 +69,12 @@ ASTNumData exec_call(AST* ast) {
|
||||
return -1000;
|
||||
}
|
||||
|
||||
ASTNumData exec_vdef(AST* ast) {
|
||||
ASTVDefData* data = (ASTVDefData*) ast->data;
|
||||
AST* val = data->val;
|
||||
return exec_exp(val);
|
||||
}
|
||||
|
||||
ASTNumData exec_vref(AST* ast) {
|
||||
return *ast_num_data_init(42.42);
|
||||
}
|
||||
|
14
src/fnv1a.c
Normal file
14
src/fnv1a.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include "include/fnv1a.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
uint64_t fnv1a_hash(char *key, size_t ln) {
|
||||
uint64_t hash = FNV1A_BASIS_64;
|
||||
|
||||
for (size_t i = 0; i < ln; i++) {
|
||||
hash ^= (unsigned char)key[i];
|
||||
hash *= FNV1A_PRIME_64;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
#include <stdio.h>
|
||||
#include "../../src/include/ast.h"
|
||||
#include "../../src/include/lexer.h"
|
||||
#include "../../src/include/dlist.h"
|
||||
|
||||
int yylex(void);
|
||||
void yyerror(char const*);
|
||||
@ -12,6 +13,7 @@
|
||||
|
||||
%code requires {
|
||||
#include "../../src/include/ast.h"
|
||||
#include "../../src/include/dlist.h"
|
||||
}
|
||||
|
||||
%union {
|
||||
@ -19,33 +21,41 @@
|
||||
char* strval;
|
||||
AST* ast;
|
||||
ArgArr* argarr;
|
||||
DList* exps;
|
||||
}
|
||||
|
||||
%define parse.error verbose
|
||||
|
||||
%token LGROUP
|
||||
%token RGROUP
|
||||
%token SEP
|
||||
%token BLOCKS // Block start {.
|
||||
%token BLOCKE // Block end }.
|
||||
|
||||
%token EXPSEP
|
||||
%token GROUPS // Group start (.
|
||||
%token GROUPE // Group end ).
|
||||
%token SEP // Seperator ,.
|
||||
|
||||
%token<strval> WORD
|
||||
%token<fval> NUM
|
||||
%token EQ // Equals =.
|
||||
|
||||
%token SUB
|
||||
%token PLUS
|
||||
%token MULT
|
||||
%token DIV
|
||||
%token EXPSEP // Expression seperator ;.
|
||||
|
||||
%token NL
|
||||
%token<strval> WORD // Word, i.e. keyword.
|
||||
%token<fval> NUM // Number.
|
||||
|
||||
%left PLUS SUB
|
||||
%left MULT DIV
|
||||
%token SUB // Subtract -.
|
||||
%token ADD // Addition *.
|
||||
%token MUL // Multiplication *.
|
||||
%token DIV // Division /.
|
||||
|
||||
%token NL // Newline.
|
||||
|
||||
%left ADD SUB
|
||||
%left MUL DIV
|
||||
%precedence NEG
|
||||
|
||||
%type<ast> exp;
|
||||
%type<argarr> arg;
|
||||
%type<argarr> argstart;
|
||||
%type<exps> blockstart;
|
||||
%type<exps> block;
|
||||
|
||||
%%
|
||||
|
||||
@ -55,7 +65,6 @@ input:
|
||||
| input EXPSEP exp { root = $3; }
|
||||
;
|
||||
|
||||
|
||||
argstart:
|
||||
exp {
|
||||
ArgArr* argarr = argarr_init();
|
||||
@ -72,9 +81,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:
|
||||
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 {
|
||||
AST** argv = calloc(2, sizeof(AST*));
|
||||
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(-1));
|
||||
@ -84,21 +116,26 @@ exp:
|
||||
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init(to, 2, argv));
|
||||
}
|
||||
|
||||
| LGROUP exp RGROUP { $$ = $2; }
|
||||
| GROUPS exp GROUPE { $$ = $2; }
|
||||
|
||||
// Variable reference.
|
||||
| WORD {
|
||||
$$ = ast_init(AST_TYPE_VREF, ast_vref_data_init($1));
|
||||
// Variable definition.
|
||||
| WORD EQ exp {
|
||||
$$ = ast_init(AST_TYPE_VDEF, ast_vdef_data_init($1, $3));
|
||||
}
|
||||
|
||||
| WORD LGROUP arg RGROUP {
|
||||
// Variable reference.
|
||||
//| WORD {
|
||||
// $$ = ast_init(AST_TYPE_VREF, ast_vref_data_init($1));
|
||||
//}
|
||||
|
||||
| WORD GROUPS arg GROUPE {
|
||||
size_t argc = $3->ln;
|
||||
AST** argv = $3->buf;
|
||||
argarr_destroypsv($3);
|
||||
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init($1, argc, argv));
|
||||
}
|
||||
|
||||
| exp PLUS exp {
|
||||
| exp ADD exp {
|
||||
AST** argv = calloc(2, sizeof(AST*));
|
||||
argv[0] = $1;
|
||||
argv[1] = $3;
|
||||
@ -116,7 +153,7 @@ exp:
|
||||
$$ = ast_init(AST_TYPE_CALL, ast_call_data_init(to, 2, argv));
|
||||
}
|
||||
|
||||
| exp MULT exp {
|
||||
| exp MUL exp {
|
||||
AST** argv = calloc(2, sizeof(AST*));
|
||||
argv[0] = $1;
|
||||
argv[1] = $3;
|
||||
|
38
src/htab.c
Normal file
38
src/htab.c
Normal file
@ -0,0 +1,38 @@
|
||||
#include "include/htab.h"
|
||||
#include "include/fnv1a.h"
|
||||
#include "include/util.h"
|
||||
#include "include/util.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
HTab* htab_init() {
|
||||
HTab* htab = calloc(1, sizeof(HTab));
|
||||
|
||||
return htab;
|
||||
}
|
||||
|
||||
void htab_destroy(HTab *htab) {
|
||||
free(htab);
|
||||
}
|
||||
|
||||
// Get the index of a key.
|
||||
size_t geti(char* key) {
|
||||
uint64_t hash = fnv1a_hash(key, strlen(key));
|
||||
size_t i = hash & (HTAB_SPACE - 1);
|
||||
return i;
|
||||
}
|
||||
|
||||
void* htab_get(HTab* htab, char* key) {
|
||||
size_t i = geti(key);
|
||||
log_dbgf("Getting something from hash table @ index %lu", i);
|
||||
return (*htab)[i];
|
||||
}
|
||||
|
||||
void htab_ins(HTab* htab, char* key, void* data) {
|
||||
size_t i = geti(key);
|
||||
assert((*htab)[i] == NULL);
|
||||
(*htab)[i] = data;
|
||||
log_dbgf("Inserted something to hash table @ index %lu", i);
|
||||
}
|
@ -4,10 +4,12 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef enum {
|
||||
AST_TYPE_NUM, // A number.
|
||||
AST_TYPE_CALL, // A function call.
|
||||
AST_TYPE_VREF, // A variable reference.
|
||||
AST_TYPE_MAX = AST_TYPE_CALL
|
||||
AST_TYPE_NUM, // A number.
|
||||
AST_TYPE_CALL, // A function call.
|
||||
AST_TYPE_VDEF, // A variable definition.
|
||||
AST_TYPE_VREF, // A variable reference.
|
||||
AST_TYPE_BLOCK, // A block of code (scope).
|
||||
AST_TYPE_MAX = AST_TYPE_BLOCK,
|
||||
} ASTType;
|
||||
|
||||
typedef struct {
|
||||
@ -36,6 +38,18 @@ ASTCallData* ast_call_data_init(char* to, size_t argc, AST** argv);
|
||||
void ast_call_data_destroy(ASTCallData* call);
|
||||
void ast_call_print(ASTCallData*, int i);
|
||||
|
||||
// A variable definition's data.
|
||||
typedef struct {
|
||||
char* name;
|
||||
AST* val;
|
||||
} ASTVDefData;
|
||||
|
||||
ASTVDefData* ast_vdef_data_init(char* name, AST* val);
|
||||
// Destroys the vdef, its name, and its ->val.
|
||||
void ast_vdef_data_destroy(ASTVDefData* vdef);
|
||||
void ast_vdef_print(ASTVDefData*, int depth);
|
||||
|
||||
// A variable reference's data.
|
||||
typedef struct {
|
||||
char* to; // What the reference's to.
|
||||
} ASTVrefData;
|
||||
@ -44,4 +58,14 @@ ASTVrefData* ast_vref_data_init(char* to);
|
||||
void ast_vref_data_destroy(ASTVrefData* call);
|
||||
void ast_vref_print(ASTVrefData*, int i);
|
||||
|
||||
typedef struct {
|
||||
AST** inside; // What's inside the block.
|
||||
size_t ln; // How many ASTs are in the block.
|
||||
} ASTBlockData;
|
||||
|
||||
ASTBlockData* ast_block_data_init(AST** inside, size_t ln);
|
||||
// Destroy a block. Also destroy all ASTs inside.
|
||||
void ast_block_data_destroy(ASTBlockData* block);
|
||||
void ast_block_data_print(ASTBlockData*, int i);
|
||||
|
||||
#endif
|
||||
|
22
src/include/dlist.h
Normal file
22
src/include/dlist.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef DLIST_H
|
||||
#define DLIST_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DLIST_INITSZ 128
|
||||
|
||||
typedef struct {
|
||||
void** buf; // The buffer containing the list.
|
||||
size_t sz; // The size of the buffer.
|
||||
size_t ln; // The number of elements in the list.
|
||||
} DList;
|
||||
|
||||
DList* dlist_init(void);
|
||||
void dlist_destroy(DList* dstr);
|
||||
// Destroy DList structure but preserve ->buf.
|
||||
void dlist_destroypsv(DList* dstr);
|
||||
|
||||
// Append src to dest.
|
||||
void dlist_append(DList* dest, void* src);
|
||||
|
||||
#endif
|
@ -6,6 +6,7 @@
|
||||
ASTNumData exec_exp(AST* ast);
|
||||
ASTNumData exec_call(AST* ast);
|
||||
ASTNumData exec_vref(AST* ast);
|
||||
ASTNumData exec_vdef(AST* ast);
|
||||
void exec_print(double n);
|
||||
|
||||
#endif
|
||||
|
17
src/include/fnv1a.h
Normal file
17
src/include/fnv1a.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef FNV1A_H
|
||||
#define FNV1A_H
|
||||
|
||||
// Implements the FNV-1a hash algorithm.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// FNV prime.
|
||||
#define FNV1A_PRIME_64 0x00000100000001b3u
|
||||
|
||||
// Offset basis.
|
||||
#define FNV1A_BASIS_64 0xcbf29ce484222325u
|
||||
|
||||
uint64_t fnv1a_hash(char* str, size_t ln);
|
||||
|
||||
#endif
|
@ -2,25 +2,27 @@
|
||||
#define HTAB_H
|
||||
|
||||
#include <stddef.h>
|
||||
#define HTAB_SPACE 128
|
||||
#include <stdint.h>
|
||||
|
||||
#define HTAB_FN fnv1a_hash // Function used for hashing.
|
||||
#define HTAB_SPACE 1024 // Number of entries possible in the hash table; must be
|
||||
// power of 2.
|
||||
|
||||
// Hash Table.
|
||||
typedef struct {} HTab;
|
||||
typedef void* HTab[HTAB_SPACE];
|
||||
|
||||
// Create a new hash table.
|
||||
HTab* htab_init();
|
||||
// Destroy a hash table.
|
||||
// Destroy a hash table, but not its elements.
|
||||
void htab_destroy(HTab* htab);
|
||||
|
||||
// Get element at `hash`. Return its contents, or NULL if nothing found.
|
||||
void* htab_get(HTab* htab, int hash);
|
||||
void* htab_get(HTab* htab, char* str);
|
||||
|
||||
// Insert `data` at index `hash`.
|
||||
void htab_ins(HTab* htab, int key, void* data);
|
||||
void htab_ins(HTab* htab, char* key, void* data);
|
||||
|
||||
// Gets the length of the hash table.
|
||||
size_t htab_ln(HTab* htab);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
15
src/lexer.c
15
src/lexer.c
@ -72,10 +72,10 @@ double acc_float(int c) {
|
||||
|
||||
char* acc_word(int c) {
|
||||
Dstr* val = dstr_init();
|
||||
do {
|
||||
while (isalpha(*inp)) {
|
||||
dstr_appendch(val, *(inp - 1));
|
||||
inp++;
|
||||
} while (isalpha(*inp));
|
||||
}
|
||||
dstr_appendch(val, *(inp - 1));
|
||||
|
||||
char* ret = val->buf;
|
||||
@ -104,15 +104,18 @@ int yylex() {
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case '+': return PLUS;
|
||||
case '+': return ADD;
|
||||
case '\n': return NL;
|
||||
case '-': return SUB;
|
||||
case '*': return MULT;
|
||||
case '*': return MUL;
|
||||
case '/': return DIV;
|
||||
case '(': return LGROUP;
|
||||
case ')': return RGROUP;
|
||||
case '(': return GROUPS;
|
||||
case ')': return GROUPE;
|
||||
case ',': return SEP;
|
||||
case ';': return EXPSEP;
|
||||
case '{': return BLOCKS;
|
||||
case '}': return BLOCKE;
|
||||
case '=': return EQ;
|
||||
default: fprintf(stderr, "Unexpected character: %c\n", c);
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ void test_ast_vref() {
|
||||
int main() {
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_ast_num);
|
||||
RUN_TEST(test_ast_call);
|
||||
//RUN_TEST(test_ast_call);
|
||||
//RUN_TEST(test_ast_vref);
|
||||
return UNITY_END();
|
||||
}
|
||||
|
27
test/test_htab.c
Normal file
27
test/test_htab.c
Normal file
@ -0,0 +1,27 @@
|
||||
#include "../src/include/htab.h"
|
||||
#include "Unity/src/unity.h"
|
||||
#include "Unity/src/unity_internals.h"
|
||||
#include <string.h>
|
||||
|
||||
void setUp() {}
|
||||
void tearDown() {}
|
||||
|
||||
void test_htab() {
|
||||
char* key = "hello";
|
||||
char* data = "world";
|
||||
|
||||
HTab* htab = htab_init();
|
||||
|
||||
htab_ins(htab, key, data);
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING(data, htab_get(htab, key));
|
||||
TEST_ASSERT_NOT_EQUAL(data, htab_get(htab, "h"));
|
||||
}
|
||||
|
||||
int main() {
|
||||
UNITY_BEGIN();
|
||||
|
||||
RUN_TEST(test_htab);
|
||||
|
||||
return UNITY_END();
|
||||
}
|
@ -7,6 +7,7 @@ bin() { ./scl.out $1 | tail -n1; }
|
||||
[ "$output" = "= 2.000000" ]
|
||||
|
||||
run bin "-1+1"
|
||||
echo $output
|
||||
[ "$output" = "= 0.000000" ]
|
||||
|
||||
run bin "1+-1"
|
||||
@ -83,15 +84,27 @@ bin() { ./scl.out $1 | tail -n1; }
|
||||
[ "$output" = "= 9.000000" ]
|
||||
}
|
||||
|
||||
@test "multiple expressions per line" {
|
||||
run bin "1+1;2"
|
||||
[ "$output" = "= 2.000000" ]
|
||||
@test "basic blocks" {
|
||||
run bin "{1}"
|
||||
[ "$output" = "= 1.000000" ]
|
||||
|
||||
run bin "2+{3;4}"
|
||||
[ "$output" = "= 6.000000" ]
|
||||
|
||||
run bin "5*{1+1;5*2}"
|
||||
echo $output
|
||||
[ "$output" = "= 50.000000" ]
|
||||
}
|
||||
|
||||
@test "variable definition" {
|
||||
run bin "x = 1"
|
||||
run bin "x=1"
|
||||
[ "$output" = "= 1.000000" ]
|
||||
|
||||
run bin "x = 1; x + 1"
|
||||
[ "$output" = "= 2.000000" ]
|
||||
# run bin "x = 1; x + 1"
|
||||
# [ "$output" = "= 2.000000" ]
|
||||
}
|
||||
|
||||
#@test "function definition" {
|
||||
# run bin "f(n)=2*n; f(2)"
|
||||
# [ "$output" = "= 4.000000" ]
|
||||
#}
|
Loading…
x
Reference in New Issue
Block a user