Compare commits
No commits in common. "bd84f3bb3ded021898c908f0a701cd9d23d1f5ba" and "8a930db33970f0a380552c1861c28c510574e9f4" have entirely different histories.
bd84f3bb3d
...
8a930db339
|
@ -1,10 +1,6 @@
|
||||||
MOD ::= EXPR*
|
MOD ::= EXPR*
|
||||||
EXPR ::=
|
EXPR ::=
|
||||||
| ASSERT
|
| ASSERT
|
||||||
| EQNE
|
|
||||||
ASSERT ::= assert EXPR
|
|
||||||
EQNE ::=
|
|
||||||
| BUILTIN
|
| BUILTIN
|
||||||
| BUILTIN eq BUILTIN
|
ASSERT ::= assert EXPR
|
||||||
| BUILTIN ne BUILTIN
|
|
||||||
BUILTIN ::= num | bool | str
|
BUILTIN ::= num | bool | str
|
||||||
|
|
|
@ -64,19 +64,6 @@ void compiler_run(compiler_t* compiler, node_t* node)
|
||||||
mod_push_instr(compiler->mod, OP_ASSERT, RZ_NO_PARAM);
|
mod_push_instr(compiler->mod, OP_ASSERT, RZ_NO_PARAM);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_NE:
|
|
||||||
case NODE_EQ: {
|
|
||||||
assert(node->children.size == 2);
|
|
||||||
|
|
||||||
for (size_t i=0; i<node->children.size; i++)
|
|
||||||
{
|
|
||||||
compiler_run(compiler, node_child(node, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
mod_push_instr(compiler->mod,
|
|
||||||
node->type == NODE_EQ ? OP_EQ : OP_NE, RZ_NO_PARAM);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
fprintf(stderr, "Cannot compile unknown node '%s'",
|
fprintf(stderr, "Cannot compile unknown node '%s'",
|
||||||
NodeTypeStr[node->type]);
|
NodeTypeStr[node->type]);
|
||||||
|
|
38
lib/lexer.c
38
lib/lexer.c
|
@ -3,13 +3,7 @@
|
||||||
|
|
||||||
#define RZ_KEYWORD(KW, NODE, VAL) \
|
#define RZ_KEYWORD(KW, NODE, VAL) \
|
||||||
{ \
|
{ \
|
||||||
node_t* kw = lexer_try_new_keyword(lexer, KW, NODE, VAL, 1); \
|
node_t* kw = lexer_try_new_keyword(lexer, KW, NODE, VAL); \
|
||||||
if (kw) { lexer_skip_spaces(lexer); return kw; } \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define RZ_TEXT(KW, NODE, VAL) \
|
|
||||||
{ \
|
|
||||||
node_t* kw = lexer_try_new_keyword(lexer, KW, NODE, VAL, 0); \
|
|
||||||
if (kw) { lexer_skip_spaces(lexer); return kw; } \
|
if (kw) { lexer_skip_spaces(lexer); return kw; } \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,11 +30,6 @@ node_t* lexer_try_new_next(lexer_t* lexer)
|
||||||
|
|
||||||
lexer_skip_spaces(lexer);
|
lexer_skip_spaces(lexer);
|
||||||
|
|
||||||
// Text
|
|
||||||
// ====
|
|
||||||
RZ_TEXT("==", NODE_EQ, 0);
|
|
||||||
RZ_TEXT("!=", NODE_NE, 0);
|
|
||||||
|
|
||||||
// Keywords
|
// Keywords
|
||||||
// ========
|
// ========
|
||||||
RZ_KEYWORD("true", NODE_BOOL, 1);
|
RZ_KEYWORD("true", NODE_BOOL, 1);
|
||||||
|
@ -167,8 +156,7 @@ void lexer_skip_spaces(lexer_t* lexer)
|
||||||
}
|
}
|
||||||
|
|
||||||
node_t* lexer_try_new_keyword(lexer_t* lexer, char* kw,
|
node_t* lexer_try_new_keyword(lexer_t* lexer, char* kw,
|
||||||
NodeType type, int has_value,
|
NodeType type, int has_value)
|
||||||
int is_kw)
|
|
||||||
{
|
{
|
||||||
assert(lexer);
|
assert(lexer);
|
||||||
assert(kw);
|
assert(kw);
|
||||||
|
@ -194,7 +182,7 @@ node_t* lexer_try_new_keyword(lexer_t* lexer, char* kw,
|
||||||
int next_idx = lexer->cursor + len;
|
int next_idx = lexer->cursor + len;
|
||||||
|
|
||||||
if (next_idx < strlen(lexer->source)
|
if (next_idx < strlen(lexer->source)
|
||||||
&& (is_kw && !lexer_is_sep(lexer, next_idx)))
|
&& !isspace(lexer->source[next_idx]))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -284,23 +272,3 @@ node_t* lexer_try_new_str(lexer_t* lexer)
|
||||||
|
|
||||||
return tok;
|
return tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lexer_is_sep(lexer_t* lexer, size_t idx)
|
|
||||||
{
|
|
||||||
assert(lexer);
|
|
||||||
|
|
||||||
if (idx >= strlen(lexer->source))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char c = lexer->source[idx];
|
|
||||||
|
|
||||||
if (isspace(c))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return c == '='
|
|
||||||
|| c == '!';
|
|
||||||
}
|
|
||||||
|
|
|
@ -20,11 +20,8 @@ NodeType lexer_peek(lexer_t* lexer, int lookahead);
|
||||||
void lexer_skip_spaces(lexer_t* lexer);
|
void lexer_skip_spaces(lexer_t* lexer);
|
||||||
|
|
||||||
node_t* lexer_try_new_keyword(lexer_t* lexer, char* kw,
|
node_t* lexer_try_new_keyword(lexer_t* lexer, char* kw,
|
||||||
NodeType type, int has_value,
|
NodeType type, int has_value);
|
||||||
int is_kw);
|
|
||||||
|
|
||||||
node_t* lexer_try_new_str(lexer_t* lexer);
|
node_t* lexer_try_new_str(lexer_t* lexer);
|
||||||
|
|
||||||
int lexer_is_sep(lexer_t* lexer, size_t idx);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
12
lib/loader.c
12
lib/loader.c
|
@ -1,5 +1,4 @@
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
#include "lib/commons.h"
|
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
|
@ -64,15 +63,6 @@ int loader_ldfile(loader_t* loader, char const* path, int debug)
|
||||||
|
|
||||||
node_t* node = parser_try_new_tree(&parser);
|
node_t* node = parser_try_new_tree(&parser);
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
char msg[RZ_STR_LIMIT];
|
|
||||||
node_str(node, msg, RZ_STR_LIMIT);
|
|
||||||
|
|
||||||
printf("\n======== AST ========\n");
|
|
||||||
printf("%s\n", msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
mod_t mod;
|
mod_t mod;
|
||||||
|
@ -112,7 +102,7 @@ int loader_ldfile(loader_t* loader, char const* path, int debug)
|
||||||
// execute
|
// execute
|
||||||
{
|
{
|
||||||
vm_t vm;
|
vm_t vm;
|
||||||
vm_init(&vm, &tysy, &err);
|
vm_init(&vm, &err);
|
||||||
|
|
||||||
int status = vm_exec_mod(&vm, &mod);
|
int status = vm_exec_mod(&vm, &mod);
|
||||||
|
|
||||||
|
|
10
lib/mod.c
10
lib/mod.c
|
@ -98,6 +98,16 @@ size_t mod_push_new_value(mod_t* mod, value_t* value)
|
||||||
assert(mod);
|
assert(mod);
|
||||||
assert(value);
|
assert(value);
|
||||||
|
|
||||||
|
for (size_t i=0; i<mod->values.size; i++)
|
||||||
|
{
|
||||||
|
if (value_eq(value, mod->values.data[i]))
|
||||||
|
{
|
||||||
|
value_free(value);
|
||||||
|
free(value);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mod->values.size == 0)
|
if (mod->values.size == 0)
|
||||||
{
|
{
|
||||||
mod->values.cap = 2;
|
mod->values.cap = 2;
|
||||||
|
|
|
@ -6,8 +6,7 @@
|
||||||
#define NODE_TYPE(G) \
|
#define NODE_TYPE(G) \
|
||||||
G(NODE_MOD), \
|
G(NODE_MOD), \
|
||||||
G(NODE_NUM), G(NODE_BOOL), G(NODE_STR), \
|
G(NODE_NUM), G(NODE_BOOL), G(NODE_STR), \
|
||||||
G(NODE_ASSERT), \
|
G(NODE_ASSERT)
|
||||||
G(NODE_EQ), G(NODE_NE)
|
|
||||||
|
|
||||||
RZ_ENUM_H(NodeType, NODE_TYPE);
|
RZ_ENUM_H(NodeType, NODE_TYPE);
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
|
|
||||||
#define OPCODES(G) \
|
#define OPCODES(G) \
|
||||||
G(OP_ASSERT), \
|
G(OP_ASSERT), \
|
||||||
G(OP_PUSH), G(OP_POP), \
|
G(OP_PUSH), G(OP_POP)
|
||||||
G(OP_EQ), G(OP_NE)
|
|
||||||
|
|
||||||
RZ_ENUM_H(Opcode, OPCODES);
|
RZ_ENUM_H(Opcode, OPCODES);
|
||||||
|
|
||||||
|
|
29
lib/parser.c
29
lib/parser.c
|
@ -61,7 +61,7 @@ node_t* parser_try_new_expr(parser_t* parser)
|
||||||
return parser_try_new_assert(parser);
|
return parser_try_new_assert(parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parser_try_new_eqne(parser);
|
return parser_try_new_builtin(parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
node_t* parser_try_new_assert(parser_t* parser)
|
node_t* parser_try_new_assert(parser_t* parser)
|
||||||
|
@ -77,33 +77,6 @@ node_t* parser_try_new_assert(parser_t* parser)
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
node_t* parser_try_new_eqne(parser_t* parser)
|
|
||||||
{
|
|
||||||
assert(parser);
|
|
||||||
node_t* lhs = parser_try_new_builtin(parser);
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
NodeType next_type = lexer_peek(parser->lexer, 1);
|
|
||||||
|
|
||||||
if (next_type == NODE_EQ || next_type == NODE_NE)
|
|
||||||
{
|
|
||||||
node_t* node = lexer_try_new_next(parser->lexer);
|
|
||||||
|
|
||||||
node_add_new_child(node, lhs);
|
|
||||||
node_add_new_child(node, parser_try_new_builtin(parser));
|
|
||||||
|
|
||||||
lhs = node;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return lhs;
|
|
||||||
}
|
|
||||||
|
|
||||||
node_t* parser_try_new_builtin(parser_t* parser)
|
node_t* parser_try_new_builtin(parser_t* parser)
|
||||||
{
|
{
|
||||||
assert(parser);
|
assert(parser);
|
||||||
|
|
|
@ -17,7 +17,6 @@ node_t* parser_try_new_tree(parser_t* parser);
|
||||||
node_t* parser_try_new_mod(parser_t* parser);
|
node_t* parser_try_new_mod(parser_t* parser);
|
||||||
node_t* parser_try_new_expr(parser_t* parser);
|
node_t* parser_try_new_expr(parser_t* parser);
|
||||||
node_t* parser_try_new_assert(parser_t* parser);
|
node_t* parser_try_new_assert(parser_t* parser);
|
||||||
node_t* parser_try_new_eqne(parser_t* parser);
|
|
||||||
node_t* parser_try_new_builtin(parser_t* parser);
|
node_t* parser_try_new_builtin(parser_t* parser);
|
||||||
|
|
||||||
node_t* parser_try_new_consume(parser_t* parser, NodeType type);
|
node_t* parser_try_new_consume(parser_t* parser, NodeType type);
|
||||||
|
|
|
@ -24,9 +24,7 @@ void prepass_run(prepass_t* prepass, node_t* node)
|
||||||
case NODE_NUM:
|
case NODE_NUM:
|
||||||
case NODE_STR:
|
case NODE_STR:
|
||||||
case NODE_BOOL:
|
case NODE_BOOL:
|
||||||
case NODE_ASSERT:
|
case NODE_ASSERT:{
|
||||||
case NODE_EQ:
|
|
||||||
case NODE_NE: {
|
|
||||||
for (size_t i=0; i<node->children.size; i++)
|
for (size_t i=0; i<node->children.size; i++)
|
||||||
{
|
{
|
||||||
prepass_run(prepass, (node_t*) node->children.data[i]);
|
prepass_run(prepass, (node_t*) node->children.data[i]);
|
||||||
|
|
46
lib/vm.c
46
lib/vm.c
|
@ -1,9 +1,8 @@
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
#include "lib/commons.h"
|
#include "lib/commons.h"
|
||||||
#include "lib/mod.h"
|
|
||||||
#include "lib/type.h"
|
#include "lib/type.h"
|
||||||
|
|
||||||
void vm_init(vm_t* vm, tysy_t* tysy, err_t* err)
|
void vm_init(vm_t* vm, err_t* err)
|
||||||
{
|
{
|
||||||
assert(vm);
|
assert(vm);
|
||||||
|
|
||||||
|
@ -11,7 +10,6 @@ void vm_init(vm_t* vm, tysy_t* tysy, err_t* err)
|
||||||
vm->bp = 0;
|
vm->bp = 0;
|
||||||
vm->sp = 0;
|
vm->sp = 0;
|
||||||
|
|
||||||
vm->tysy = tysy;
|
|
||||||
vm->err = err;
|
vm->err = err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,24 +18,6 @@ void vm_free(vm_t* vm)
|
||||||
assert(vm);
|
assert(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vm_push_value(vm_t* vm, mod_t* mod, value_t* value)
|
|
||||||
{
|
|
||||||
assert(vm);
|
|
||||||
assert(value);
|
|
||||||
|
|
||||||
param_t param = mod_push_new_value(mod, value);
|
|
||||||
vm_push(vm, param);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vm_push(vm_t* vm, param_t param)
|
|
||||||
{
|
|
||||||
assert(vm);
|
|
||||||
assert(vm->sp + 1 < RZ_STACK_LIMIT);
|
|
||||||
|
|
||||||
vm->stack[vm->sp] = param;
|
|
||||||
vm->sp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
param_t vm_pop(vm_t* vm)
|
param_t vm_pop(vm_t* vm)
|
||||||
{
|
{
|
||||||
assert(vm);
|
assert(vm);
|
||||||
|
@ -131,30 +111,6 @@ int vm_exec_instr(vm_t* vm, mod_t* mod, Opcode op, param_t param)
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case OP_NE:
|
|
||||||
case OP_EQ: {
|
|
||||||
int l = vm_pop(vm);
|
|
||||||
int r = vm_pop(vm);
|
|
||||||
assert(l != -1);
|
|
||||||
assert(r != -1);
|
|
||||||
|
|
||||||
value_t* rhs = mod->values.data[l];
|
|
||||||
value_t* lhs = mod->values.data[r];
|
|
||||||
|
|
||||||
int same_type = lhs->type->kind == rhs->type->kind;
|
|
||||||
int eq = value_eq(lhs, rhs);
|
|
||||||
|
|
||||||
value_t* res = tysy_new_bool(vm->tysy,
|
|
||||||
(op == OP_EQ
|
|
||||||
? (same_type && eq)
|
|
||||||
: (!same_type || !eq)),
|
|
||||||
rhs->line);
|
|
||||||
|
|
||||||
vm_push_value(vm, mod, res);
|
|
||||||
|
|
||||||
vm->pc++;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
fprintf(stderr, "Cannot execute unknown opcode '%s'.\n",
|
fprintf(stderr, "Cannot execute unknown opcode '%s'.\n",
|
||||||
OpcodeStr[op]);
|
OpcodeStr[op]);
|
||||||
|
|
6
lib/vm.h
6
lib/vm.h
|
@ -5,10 +5,8 @@
|
||||||
#include "opcodes.h"
|
#include "opcodes.h"
|
||||||
#include "mod.h"
|
#include "mod.h"
|
||||||
#include "err.h"
|
#include "err.h"
|
||||||
#include "tysy.h"
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
tysy_t* tysy;
|
|
||||||
param_t stack[RZ_STACK_LIMIT];
|
param_t stack[RZ_STACK_LIMIT];
|
||||||
size_t pc;
|
size_t pc;
|
||||||
size_t bp;
|
size_t bp;
|
||||||
|
@ -17,11 +15,9 @@ typedef struct {
|
||||||
err_t* err;
|
err_t* err;
|
||||||
} vm_t;
|
} vm_t;
|
||||||
|
|
||||||
void vm_init(vm_t* vm, tysy_t* tysy, err_t* err);
|
void vm_init(vm_t* vm, err_t* err);
|
||||||
void vm_free(vm_t* vm);
|
void vm_free(vm_t* vm);
|
||||||
|
|
||||||
void vm_push_value(vm_t* vm, mod_t* mod, value_t* value);
|
|
||||||
void vm_push(vm_t* vm, param_t param);
|
|
||||||
param_t vm_pop(vm_t* vm);
|
param_t vm_pop(vm_t* vm);
|
||||||
|
|
||||||
size_t vm_stack_str(vm_t* vm, char* buffer, size_t size);
|
size_t vm_stack_str(vm_t* vm, char* buffer, size_t size);
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
assert 5 == 5
|
|
||||||
assert 3 != 5
|
|
||||||
|
|
||||||
assert true == true
|
|
||||||
assert false == false
|
|
||||||
assert false != true
|
|
||||||
|
|
||||||
assert "hello" == "hello"
|
|
||||||
assert "world" != "hello"
|
|
||||||
|
|
||||||
assert 7 != "hello"
|
|
||||||
assert false != 23
|
|
||||||
assert "bim" != true
|
|
|
@ -14,6 +14,8 @@ do
|
||||||
TRACE="$(roza $file 2>&1)"
|
TRACE="$(roza $file 2>&1)"
|
||||||
RES=$?
|
RES=$?
|
||||||
|
|
||||||
|
# echo -en "\e[33m$file\e[0m ... "
|
||||||
|
|
||||||
if [ $RES -ne 0 ]
|
if [ $RES -ne 0 ]
|
||||||
then
|
then
|
||||||
echo
|
echo
|
||||||
|
@ -30,7 +32,14 @@ do
|
||||||
TOTAL=$(($TOTAL + 1))
|
TOTAL=$(($TOTAL + 1))
|
||||||
done
|
done
|
||||||
|
|
||||||
echo -e "\e[33m$H SUMMARY $H\e[0m"
|
echo
|
||||||
|
|
||||||
|
if [ $PASSED -eq $TOTAL ]
|
||||||
|
then
|
||||||
|
echo -e "\e[32m$H All tests passed $H\e[0m"
|
||||||
|
else
|
||||||
|
echo -e "\e[31m$H Some tests failed $H\e[0m"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "PASSED: $PASSED"
|
echo "PASSED: $PASSED"
|
||||||
for ok in $PASSED_LST
|
for ok in $PASSED_LST
|
||||||
|
@ -48,10 +57,3 @@ done
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "TOTAL: $TOTAL"
|
echo "TOTAL: $TOTAL"
|
||||||
|
|
||||||
if [ $PASSED -eq $TOTAL ]
|
|
||||||
then
|
|
||||||
echo -e "\e[32m$H All tests passed $H\e[0m"
|
|
||||||
else
|
|
||||||
echo -e "\e[31m$H Some tests failed $H\e[0m"
|
|
||||||
fi
|
|
||||||
|
|
|
@ -8,13 +8,13 @@ static void test_lexer_ok(char const* oracle, char const* source)
|
||||||
lexer_init(&lex, source, NULL);
|
lexer_init(&lex, source, NULL);
|
||||||
|
|
||||||
node_t* tok = lexer_try_new_next(&lex);
|
node_t* tok = lexer_try_new_next(&lex);
|
||||||
cr_assert(tok != NULL, "error -> %s", source);
|
cr_assert(tok != NULL);
|
||||||
|
|
||||||
size_t const SZ = 512;
|
size_t const SZ = 512;
|
||||||
char str[SZ];
|
char str[SZ];
|
||||||
node_str(tok, str, SZ);
|
node_str(tok, str, SZ);
|
||||||
|
|
||||||
cr_assert_str_eq(str, oracle, "error -> %s", source);
|
cr_assert_str_eq(str, oracle);
|
||||||
|
|
||||||
node_free(tok);
|
node_free(tok);
|
||||||
lexer_free(&lex);
|
lexer_free(&lex);
|
||||||
|
@ -30,7 +30,7 @@ static void test_lexer_ko(char const* source)
|
||||||
|
|
||||||
node_t* tok = lexer_try_new_next(&lex);
|
node_t* tok = lexer_try_new_next(&lex);
|
||||||
|
|
||||||
cr_assert(tok == NULL, "error -> %s", source);
|
cr_assert(tok == NULL);
|
||||||
cr_assert(err.size > 0);
|
cr_assert(err.size > 0);
|
||||||
|
|
||||||
err_free(&err);
|
err_free(&err);
|
||||||
|
@ -48,7 +48,7 @@ static void test_lexer(char const* source, size_t n, ...)
|
||||||
for (size_t i=0; i<n; i++)
|
for (size_t i=0; i<n; i++)
|
||||||
{
|
{
|
||||||
node_t* tok = lexer_try_new_next(&lexer);
|
node_t* tok = lexer_try_new_next(&lexer);
|
||||||
cr_assert(NULL != tok, "error -> %s", source);
|
cr_assert(NULL != tok);
|
||||||
|
|
||||||
size_t const SZ = 256;
|
size_t const SZ = 256;
|
||||||
char tok_str[SZ];
|
char tok_str[SZ];
|
||||||
|
@ -109,19 +109,3 @@ Test(lexer, str) {
|
||||||
Test(lexer, assert) {
|
Test(lexer, assert) {
|
||||||
test_lexer("assert", 1, "ASSERT");
|
test_lexer("assert", 1, "ASSERT");
|
||||||
}
|
}
|
||||||
|
|
||||||
Test(lexer, cmp) {
|
|
||||||
test_lexer("== !=", 2,
|
|
||||||
"EQ",
|
|
||||||
"NE");
|
|
||||||
|
|
||||||
test_lexer("false==true", 3,
|
|
||||||
"BOOL[false]",
|
|
||||||
"EQ",
|
|
||||||
"BOOL[true]");
|
|
||||||
|
|
||||||
test_lexer("false!=true", 3,
|
|
||||||
"BOOL[false]",
|
|
||||||
"NE",
|
|
||||||
"BOOL[true]");
|
|
||||||
}
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ static void test_parser_ok(char const* oracle, char const* source)
|
||||||
|
|
||||||
node_t* node = parser_try_new_tree(&parser);
|
node_t* node = parser_try_new_tree(&parser);
|
||||||
|
|
||||||
cr_assert(NULL != node, "error -> %s", source);
|
cr_assert(NULL != node);
|
||||||
|
|
||||||
size_t const SZ = 256;
|
size_t const SZ = 256;
|
||||||
char msg[SZ];
|
char msg[SZ];
|
||||||
|
@ -71,8 +71,3 @@ Test(parser, assert) {
|
||||||
test_parser_ok("MOD(ASSERT(BOOL[false]))", " assert false ");
|
test_parser_ok("MOD(ASSERT(BOOL[false]))", " assert false ");
|
||||||
test_parser_ok("MOD(ASSERT(BOOL[true]))", " assert true ");
|
test_parser_ok("MOD(ASSERT(BOOL[true]))", " assert true ");
|
||||||
}
|
}
|
||||||
|
|
||||||
Test(parser, eqne) {
|
|
||||||
test_parser_ok("MOD(EQ(NUM[3],NUM[3]))", " 3 == 3 ");
|
|
||||||
test_parser_ok("MOD(NE(NUM[3],NUM[3]))", " 3 != 3 ");
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue