Compare commits
13 Commits
v0.1
...
3fcffc81ad
Author | SHA1 | Date | |
---|---|---|---|
3fcffc81ad | |||
27e61471a8 | |||
c94d7863a7 | |||
4dd1f2b5f1 | |||
1a2249a0da | |||
8b01407374 | |||
3ab2696705 | |||
0293c925d2 | |||
16d62f280f | |||
0dbeff7077 | |||
96038f4baa | |||
6d7ff5d43f | |||
868ee84aeb |
7
Makefile
7
Makefile
@@ -35,6 +35,7 @@ TEST_VAL_DIR = $(TEST_DIR)/validation
|
||||
RESETCOLOR = \033[0m
|
||||
WHITE = $(RESETCOLOR)\033[37m
|
||||
WHITE_BOLD = $(RESETCOLOR)\033[37;1m
|
||||
RED_BOLD = $(RESETCOLOR)\033[31;1m
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
@@ -81,18 +82,20 @@ $(UNITY_OBJ): $(UNITY_C) $(UNITY_H)
|
||||
|
||||
# Compile test object.
|
||||
$(TEST_OBJ_DIR)/test_%.o: $(TEST_DIR)/test_%.c
|
||||
@ mkdir -p $(TEST_OBJ_DIR)
|
||||
@ $(PRINT) "$(WHITE_BOLD)Compiling test object $(WHITE)$@$(WHITE_BOLD)...$(RESETCOLOR)"
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
# Link final test binary.
|
||||
$(TEST_BUILD_DIR)/test_%.out: $(TEST_OBJ_DIR)/test_%.o $(OBJ_DIR)/%.o $(UNITY_OBJ)
|
||||
$(TEST_BUILD_DIR)/test_%.out: $(TEST_OBJ_DIR)/test_%.o $(OBJ_DIR)/grammar.o $(OBJ_FILES_NOMAIN) $(UNITY_OBJ)
|
||||
@ mkdir -p $(TEST_BUILD_DIR)
|
||||
@ $(PRINT) "$(WHITE_BOLD)Linking test binary $(WHITE)$@$(WHITE_BOLD)...$(RESETCOLOR)"
|
||||
$(LINK) -o $@ $? $(LDFLAGS)
|
||||
|
||||
# Run the test files.
|
||||
test: $(TARGET) $(TEST_BIN_FILES)
|
||||
@ $(PRINT) "$(WHITE_BOLD)Running unit tests...$(RESETCOLOR)"
|
||||
for test in $(TEST_BIN_FILES); do ./$${test}; done
|
||||
for test in $(TEST_BIN_FILES); do ./$${test} || echo -e "$(RED_BOLD) BAD EXIT ON $${test} $(RESETCOLOR)"; done
|
||||
@ $(PRINT) "$(WHITE_BOLD)Running validation tests...$(RESETCOLOR)"
|
||||
$(BATS) $(TEST_VAL_DIR)
|
||||
|
||||
|
15
README.md
15
README.md
@@ -5,9 +5,18 @@ Version v1.0-alpha
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
git clone https://git.signorovitch.org/jacob/scl && cd scl
|
||||
make release # Build.
|
||||
./scl # Run.
|
||||
git clone https://git.signorovitch.org/jacob/scl -b stable
|
||||
cd scl
|
||||
make release
|
||||
./scl.out
|
||||
```
|
||||
|
||||
### For Development
|
||||
|
||||
```bash
|
||||
git clone git@signorovitch.org:jacob/scl --recurse-submodules && cd scl
|
||||
make all test
|
||||
./scl.out
|
||||
```
|
||||
|
||||
If you wish to run tests, make sure to run `git clone --recurse-submodules` to
|
||||
|
14
src/ast.c
14
src/ast.c
@@ -27,6 +27,7 @@ void ast_destroy(AST* ast) {
|
||||
switch (ast->type) {
|
||||
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;
|
||||
default:
|
||||
log_dbgf("Unknown ast type %d (max: %d)", ast->type, AST_TYPE_MAX);
|
||||
}
|
||||
@@ -103,9 +104,18 @@ void ast_call_print(ASTCallData* data, int i) {
|
||||
INDENT_END;
|
||||
}
|
||||
|
||||
ASTVrefData* ast_vref_data_init(char* to) {}
|
||||
ASTVrefData* ast_vref_data_init(char* to) {
|
||||
talloc(ASTVrefData, vref);
|
||||
|
||||
void ast_vref_data_destroy(ASTVrefData* vref) {}
|
||||
vref->to = to;
|
||||
|
||||
return vref;
|
||||
}
|
||||
|
||||
void ast_vref_data_destroy(ASTVrefData* vref) {
|
||||
free(vref->to);
|
||||
free(vref);
|
||||
}
|
||||
|
||||
void ast_vref_print(ASTVrefData* data, int i) {
|
||||
INDENT_BEGIN(i);
|
||||
|
@@ -13,6 +13,7 @@ ASTNumData exec_exp(AST* ast) {
|
||||
switch (ast->type) {
|
||||
case AST_TYPE_CALL: return exec_call(ast);
|
||||
case AST_TYPE_NUM: return *(ASTNumData*)ast->data;
|
||||
case AST_TYPE_VREF: return exec_vref(ast);
|
||||
default: printf("what\n");
|
||||
exit(1);
|
||||
}
|
||||
@@ -67,4 +68,8 @@ ASTNumData exec_call(AST* ast) {
|
||||
return -1000;
|
||||
}
|
||||
|
||||
ASTNumData exec_vref(AST* ast) {
|
||||
return *ast_num_data_init(42.42);
|
||||
}
|
||||
|
||||
void exec_print(double n) { printf("= %lf\n", n); }
|
||||
|
6
src/global.c
Normal file
6
src/global.c
Normal file
@@ -0,0 +1,6 @@
|
||||
#include "include/global.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// Global input text.
|
||||
char* inp = NULL;
|
@@ -27,6 +27,8 @@
|
||||
%token RGROUP
|
||||
%token SEP
|
||||
|
||||
%token EXPSEP
|
||||
|
||||
%token<strval> WORD
|
||||
%token<fval> NUM
|
||||
|
||||
@@ -50,6 +52,7 @@
|
||||
input:
|
||||
%empty
|
||||
| exp { root = $1; }
|
||||
| input EXPSEP exp { root = $3; }
|
||||
;
|
||||
|
||||
|
||||
@@ -84,7 +87,9 @@ exp:
|
||||
| LGROUP exp RGROUP { $$ = $2; }
|
||||
|
||||
// Variable reference.
|
||||
//| WORD
|
||||
| WORD {
|
||||
$$ = ast_init(AST_TYPE_VREF, ast_vref_data_init($1));
|
||||
}
|
||||
|
||||
| WORD LGROUP arg RGROUP {
|
||||
size_t argc = $3->ln;
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DSTR_INITSZ 2
|
||||
#define DSTR_INITSZ 128
|
||||
|
||||
typedef struct {
|
||||
char* buf; // The buffer containing the string.
|
||||
|
@@ -5,6 +5,7 @@
|
||||
|
||||
ASTNumData exec_exp(AST* ast);
|
||||
ASTNumData exec_call(AST* ast);
|
||||
ASTNumData exec_vref(AST* ast);
|
||||
void exec_print(double n);
|
||||
|
||||
#endif
|
||||
|
4
src/include/global.h
Normal file
4
src/include/global.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#ifndef GLOBAL_H
|
||||
#define GLOBAL_H
|
||||
|
||||
#endif
|
@@ -112,6 +112,7 @@ int yylex() {
|
||||
case '(': return LGROUP;
|
||||
case ')': return RGROUP;
|
||||
case ',': return SEP;
|
||||
case ';': return EXPSEP;
|
||||
default: fprintf(stderr, "Unexpected character: %c\n", c);
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "include/global.h"
|
||||
#include "include/ast.h"
|
||||
#include "include/dstr.h"
|
||||
#include "include/exec.h"
|
||||
@@ -11,10 +12,7 @@
|
||||
|
||||
// Global Abstract Syntax Tree.
|
||||
extern AST* root;
|
||||
|
||||
// Global input text.
|
||||
char* inp = NULL;
|
||||
|
||||
extern char* inp;
|
||||
extern int yyparse();
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
59
test/test_ast.c
Normal file
59
test/test_ast.c
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "../src/include/ast.h"
|
||||
#include "Unity/src/unity.h"
|
||||
#include "Unity/src/unity_internals.h"
|
||||
#include <string.h>
|
||||
|
||||
void setUp() {}
|
||||
void tearDown() {}
|
||||
|
||||
void test_ast_num() {
|
||||
ASTNumData* num = ast_num_data_init(12.0);
|
||||
AST* ast = ast_init(AST_TYPE_NUM, num);
|
||||
|
||||
TEST_ASSERT_EQUAL(AST_TYPE_NUM, ast->type);
|
||||
TEST_ASSERT_EQUAL(12.0, *(ASTNumData*)ast->data);
|
||||
|
||||
ast_destroy(ast);
|
||||
}
|
||||
|
||||
void test_ast_call() {
|
||||
AST** argv = malloc(2*sizeof(AST*));
|
||||
argv[0] = ast_init(AST_TYPE_NUM, ast_num_data_init(1.0));
|
||||
argv[1] = ast_init(AST_TYPE_NUM, ast_num_data_init(2.0));
|
||||
|
||||
char* name = malloc(2);
|
||||
strcpy(name, "f");
|
||||
|
||||
ASTCallData* call = ast_call_data_init(name, 2, argv);
|
||||
|
||||
AST* ast = ast_init(AST_TYPE_CALL, call);
|
||||
|
||||
TEST_ASSERT_EQUAL(AST_TYPE_CALL, ast->type);
|
||||
TEST_ASSERT_EQUAL(name, ((ASTCallData*)ast->data)->to);
|
||||
TEST_ASSERT_EQUAL(2, ((ASTCallData*)ast->data)->argc);
|
||||
TEST_ASSERT_EQUAL(1.0, ((ASTCallData*)ast->data)->argv[0]);
|
||||
TEST_ASSERT_EQUAL(2.0, ((ASTCallData*)ast->data)->argv[1]);
|
||||
|
||||
ast_destroy(ast);
|
||||
}
|
||||
|
||||
void test_ast_vref() {
|
||||
char* s = malloc(2);
|
||||
strcpy(s, "x");
|
||||
ASTVrefData* vref = ast_vref_data_init(s);
|
||||
AST* ast = ast_init(AST_TYPE_VREF, vref);
|
||||
|
||||
TEST_ASSERT_EQUAL(AST_TYPE_VREF, ast->type);
|
||||
ASTVrefData data = *(ASTVrefData*)ast->data;
|
||||
TEST_ASSERT_EQUAL_STRING("x", data.to);
|
||||
|
||||
//ast_destroy(ast);
|
||||
}
|
||||
|
||||
int main() {
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_ast_num);
|
||||
RUN_TEST(test_ast_call);
|
||||
//RUN_TEST(test_ast_vref);
|
||||
return UNITY_END();
|
||||
}
|
@@ -9,7 +9,7 @@ void test_dstr_init() {
|
||||
Dstr* dstr = dstr_init();
|
||||
TEST_ASSERT_EQUAL(0, strlen(dstr->buf));
|
||||
TEST_ASSERT_EQUAL(0, dstr->ln);
|
||||
TEST_ASSERT_EQUAL(DSTR_INITSZ, dstr->bufsz);
|
||||
TEST_ASSERT_EQUAL(DSTR_INITSZ, dstr->sz);
|
||||
}
|
||||
|
||||
void test_dstr_append() {
|
||||
@@ -22,7 +22,7 @@ void test_dstr_append() {
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING(hello_world, dstr->buf);
|
||||
TEST_ASSERT_EQUAL(strlen(hello_world), dstr->ln);
|
||||
TEST_ASSERT_EQUAL(DSTR_INITSZ, dstr->bufsz);
|
||||
TEST_ASSERT_EQUAL(DSTR_INITSZ, dstr->sz);
|
||||
|
||||
dstr_destroy(dstr);
|
||||
|
||||
@@ -36,7 +36,7 @@ void test_dstr_append() {
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING(h, dstr->buf);
|
||||
TEST_ASSERT_EQUAL(strlen(h), dstr->ln);
|
||||
TEST_ASSERT_EQUAL(DSTR_INITSZ * 2, dstr->bufsz);
|
||||
TEST_ASSERT_EQUAL(DSTR_INITSZ * 2, dstr->sz);
|
||||
}
|
||||
|
||||
void test_dstr_appendch() {
|
||||
@@ -50,7 +50,7 @@ void test_dstr_appendch() {
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING(c_str, dstr->buf);
|
||||
TEST_ASSERT_EQUAL(strlen(c_str), dstr->ln);
|
||||
TEST_ASSERT_EQUAL(DSTR_INITSZ, dstr->bufsz);
|
||||
TEST_ASSERT_EQUAL(DSTR_INITSZ, dstr->sz);
|
||||
|
||||
dstr_destroy(dstr);
|
||||
|
||||
@@ -66,11 +66,10 @@ void test_dstr_appendch() {
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING(h, dstr->buf);
|
||||
TEST_ASSERT_EQUAL(strlen(h), dstr->ln);
|
||||
TEST_ASSERT_EQUAL(DSTR_INITSZ * 2, dstr->bufsz);
|
||||
TEST_ASSERT_EQUAL(DSTR_INITSZ * 2, dstr->sz);
|
||||
}
|
||||
|
||||
// not needed when using generate_test_runner.rb
|
||||
int main(void) {
|
||||
int main() {
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_dstr_init);
|
||||
RUN_TEST(test_dstr_append);
|
||||
|
@@ -82,3 +82,16 @@ bin() { ./scl.out $1 | tail -n1; }
|
||||
run bin "-(-(1+2)*3)"
|
||||
[ "$output" = "= 9.000000" ]
|
||||
}
|
||||
|
||||
@test "multiple expressions per line" {
|
||||
run bin "1+1;2"
|
||||
[ "$output" = "= 2.000000" ]
|
||||
}
|
||||
|
||||
@test "variable definition" {
|
||||
run bin "x = 1"
|
||||
[ "$output" = "= 1.000000" ]
|
||||
|
||||
run bin "x = 1; x + 1"
|
||||
[ "$output" = "= 2.000000" ]
|
||||
}
|
||||
|
Reference in New Issue
Block a user