bool literals.

main
bog 2023-12-09 22:59:24 +01:00
parent 46dc8b8c2d
commit dc4a74ad15
14 changed files with 160 additions and 11 deletions

View File

@ -1,2 +1,3 @@
MOD ::= EXPR*
EXPR ::= num
EXPR ::= BUILTIN
BUILTIN ::= num | bool

View File

@ -40,6 +40,15 @@ void compiler_run(compiler_t* compiler, node_t* node)
} break;
case NODE_BOOL: {
int value = strcmp(node->value.data, "true") == 0;
value_t* val = tysy_new_bool(compiler->tysy, value);
Opcode op = OP_PUSH;
param_t param = (param_t) mod_push_new_value(compiler->mod, val);
mod_push_instr(compiler->mod, op, param);
} break;
default: {
char msg[RZ_STR_LIMIT];
snprintf(msg, RZ_STR_LIMIT, "Unknown node '%s'",

View File

@ -36,6 +36,15 @@ node_t* lexer_try_new_next(lexer_t* lexer)
}
}
{
node_t* kw = lexer_try_new_keyword(lexer, "true", NODE_BOOL, 1);
if (kw) { return kw; }
}
{
node_t* kw = lexer_try_new_keyword(lexer, "false", NODE_BOOL, 1);
if (kw) { return kw; }
}
// scan num
{
size_t cursor = lexer->cursor;
@ -93,3 +102,72 @@ node_t* lexer_try_new_next(lexer_t* lexer)
return NULL;
}
NodeType lexer_peek(lexer_t* lexer, int lookahead)
{
assert(lexer);
size_t cursor = lexer->cursor;
int line = lexer->line;
NodeType type = 0;
for (int i=0; i<lookahead; i++)
{
node_t* node = lexer_try_new_next(lexer);
if (node)
{
type = node->type;
node_free(node);
free(node);
}
}
lexer->cursor = cursor;
lexer->line = line;
return type;
}
node_t* lexer_try_new_keyword(lexer_t* lexer, char* kw,
NodeType type, int has_value)
{
assert(lexer);
assert(kw);
size_t len = strlen(kw);
size_t cursor = lexer->cursor;
if (cursor + len <= strlen(lexer->source))
{
int ok = 1;
for (size_t i=cursor; i<cursor + len; i++)
{
if (lexer->source[i] != kw[i - cursor])
{
ok = 0;
break;
}
}
if (ok)
{
int next_idx = lexer->cursor + len;
if (next_idx < strlen(lexer->source)
&& !isspace(lexer->source[next_idx]))
{
return NULL;
}
node_t* node = malloc(sizeof(node_t));
node_init(node, type, has_value ? (char*) kw : "", lexer->line);
lexer->cursor += len;
return node;
}
}
return NULL;
}

View File

@ -16,5 +16,9 @@ void lexer_init(lexer_t* lexer, char const* source, err_t* err);
void lexer_free(lexer_t* lexer);
node_t* lexer_try_new_next(lexer_t* lexer);
NodeType lexer_peek(lexer_t* lexer, int lookahead);
node_t* lexer_try_new_keyword(lexer_t* lexer, char* kw,
NodeType type, int has_value);
#endif

View File

@ -5,7 +5,8 @@
#define NODE_TYPE(G) \
G(NODE_MOD), \
G(NODE_NUM)
G(NODE_NUM), \
G(NODE_BOOL)
RZ_ENUM_H(NodeType, NODE_TYPE);

View File

@ -49,13 +49,20 @@ node_t* parser_try_new_mod(parser_t* parser)
node_t* parser_try_new_expr(parser_t* parser)
{
assert(parser);
return parser_try_new_num(parser);
return parser_try_new_builtin(parser);
}
node_t* parser_try_new_num(parser_t* parser)
node_t* parser_try_new_builtin(parser_t* parser)
{
assert(parser);
return parser_try_new_consume(parser, NODE_NUM);
NodeType next = lexer_peek(parser->lexer, 1);
if (next == NODE_NUM || next == NODE_BOOL)
{
return parser_try_new_consume(parser, next);
}
return NULL;
}
node_t* parser_try_new_consume(parser_t* parser, NodeType type)

View File

@ -16,7 +16,7 @@ void parser_free(parser_t* parser);
node_t* parser_try_new_tree(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_num(parser_t* parser);
node_t* parser_try_new_builtin(parser_t* parser);
node_t* parser_try_new_consume(parser_t* parser, NodeType type);

View File

@ -4,7 +4,8 @@
#include "commons.h"
#define TYPE_KIND(G) \
G(TYPE_NUM)
G(TYPE_NUM), \
G(TYPE_BOOL)
RZ_ENUM_H(TypeKind, TYPE_KIND);

View File

@ -7,9 +7,16 @@ void tysy_init(tysy_t* tysy)
// num
{
type_t* num = malloc(sizeof(type_t));
type_init(num, TYPE_NUM);
tysy_register_new_type(tysy, "num", num);
type_t* ty = malloc(sizeof(type_t));
type_init(ty, TYPE_NUM);
tysy_register_new_type(tysy, "num", ty);
}
// bool
{
type_t* ty = malloc(sizeof(type_t));
type_init(ty, TYPE_BOOL);
tysy_register_new_type(tysy, "bool", ty);
}
}
@ -65,3 +72,14 @@ value_t* tysy_new_num(tysy_t* tysy, double value)
return val;
}
value_t* tysy_new_bool(tysy_t* tysy, int value)
{
assert(tysy);
value_t* val = malloc(sizeof(value_t));
value_init(val, tysy_try_find_type(tysy, "bool"));
val->value.bool = value;
return val;
}

View File

@ -17,5 +17,6 @@ void tysy_register_new_type(tysy_t* tysy, char* name, type_t* type);
type_t* tysy_try_find_type(tysy_t* tysy, char* name);
value_t* tysy_new_num(tysy_t* tysy, double value);
value_t* tysy_new_bool(tysy_t* tysy, int value);
#endif

View File

@ -26,6 +26,10 @@ int value_eq(value_t* value, value_t* rhs)
return value->value.num == rhs->value.num;
} break;
case TYPE_BOOL: {
return value->value.bool == rhs->value.bool;
} break;
default: {
fprintf(stderr, "Cannot compare value of type '%s'.\n",
TypeKindStr[value->type->kind]);
@ -47,6 +51,14 @@ size_t value_str(value_t* value, char* buffer, size_t size)
return snprintf(buffer, size, "%lf", value->value.num);
break;
default: return 0;
case TYPE_BOOL:
return snprintf(buffer, size, "%s", value->value.bool ? "true" : "false");
break;
default: {
fprintf(stderr, "Cannot stringify unknown value of type '%s'.\n",
TypeKindStr[value->type->kind]);
abort();
};
}
}

View File

@ -8,6 +8,7 @@ typedef struct {
union {
double num;
int bool;
} value;
} value_t;

View File

@ -81,3 +81,15 @@ Test(lexer, num) {
test_lexer_ko("..2");
test_lexer_ko("2..");
}
Test(lexer, bool) {
test_lexer_ko("true3");
test_lexer_ko("1true");
test_lexer_ko("afalse");
test_lexer_ko("falset");
test_lexer("true 3 false", 3,
"BOOL[true]",
"NUM[3]",
"BOOL[false]");
}

View File

@ -58,3 +58,7 @@ Test(parser, num) {
test_parser_ko(" § ");
}
Test(parser, bool) {
test_parser_ok("MOD(BOOL[true],BOOL[false])", "true false");
}