ADD: 'is' keyword to test an expression against a type.

main
bog 2023-08-26 11:26:51 +02:00
parent 76497315da
commit 9bb5a60b2a
9 changed files with 77 additions and 7 deletions

View File

@ -60,6 +60,11 @@ void compile_node(compiler* self, node* root, program* prog)
free(ty);
cstatic_free(&cs);
}
else if (root->type == NODE_IS)
{
compile_children(self, root, prog);
program_add_instr(prog, OP_TEQ, NO_PARAM);
}
else if (root->type == NODE_VARDECL)
{
cstatic cs;
@ -463,6 +468,11 @@ type* compile_get_type(compiler* self, node* root)
type_init(ty, TY_BOOLEAN);
}
else if (strcmp(root->value, "type") == 0)
{
type_init(ty, TY_TYPE);
}
else if (strcmp(root->value, "array") == 0)
{
type_init(ty, TY_ARRAY);

View File

@ -201,7 +201,8 @@ type* cstatic_resolve_new(cstatic* self, symtable* sym, node* ast)
|| ast->type == NODE_GT
|| ast->type == NODE_GE
|| ast->type == NODE_EQ
|| ast->type == NODE_NE)
|| ast->type == NODE_NE
|| ast->type == NODE_IS)
{
return cstatic_new_type(self, TY_BOOLEAN);

View File

@ -13,7 +13,7 @@ BOOLEAN true|false
INTEGER -?[0-9]+
FLOAT -?[0-9]+\.[0-9]+
STRING \"[^"]*\"
TYPE (int|float|bool|str|array)
TYPE (int|float|bool|str|array|type)
IDENT [_A-Za-z][_A-Za-z0-9]*
%%
@ -25,7 +25,7 @@ IDENT [_A-Za-z][_A-Za-z0-9]*
yylval.str = str_new(yytext);
return TYPE;
}
"is" { return IS; }
"do" { return DO; }
"end" { return END; }
"let!" { return LET_MUT; }

View File

@ -12,7 +12,7 @@
G(NODE_MUL), G(NODE_DIV), G(NODE_MOD), G(NODE_POW), \
G(NODE_ARRAY), G(NODE_INDEX), G(NODE_LT), G(NODE_LE), \
G(NODE_GT), G(NODE_GE), G(NODE_VARDECL), G(NODE_IDENT), \
G(NODE_CONSTDECL), G(NODE_ASSIGN), G(NODE_DO)
G(NODE_CONSTDECL), G(NODE_ASSIGN), G(NODE_DO), G(NODE_IS)
#include "mutils.h"

View File

@ -44,7 +44,8 @@
G(OP_FGE), \
G(OP_STORE), \
G(OP_LOAD), \
G(OP_ASTORE)
G(OP_ASTORE), \
G(OP_TEQ)
enum Opcodes {

View File

@ -37,6 +37,7 @@
%token OSQUARE CSQUARE COMMA
%token LET LET_MUT ASSIGN DO END
%type <n_children> expr_unop
%left IS
%%
@ -78,9 +79,24 @@ exprs:
expr:
// TYPE OPERATORS
expr IS type {
node* n = malloc(sizeof(node));
node_init(n, NODE_IS, "", line);
node* rhs = stack_pop();
node* lhs = stack_pop();
node_add_child(n, lhs);
node_add_child(n, rhs);
stack_push(n);
$$ = 1;
}
// BLOCK
DO exprs END {
node *n = malloc(sizeof(node));
| DO exprs END {
node* n = malloc(sizeof(node));
node_init(n, NODE_DO, "", line);
size_t const SZ = $2;

View File

@ -104,6 +104,8 @@ void vm_exec(vm* self, program* prog)
case OP_STORE: vm_store(self, param); break;
case OP_ASTORE: vm_astore(self, param); break;
case OP_TEQ: vm_teq(self); break;
default: {
fprintf(stderr, "unknown opcode %s\n",
OpcodesStr[opcode]);
@ -1093,3 +1095,25 @@ void vm_astore(vm* self, int param)
self->pc++;
}
void vm_teq(vm* self)
{
assert(self);
value* type_val = vm_pop_value(self);
value* expr_val = vm_pop_value(self);
type* ty = type_val->val.type_val;
int equals = type_equals(ty, expr_val->type);
value* val = malloc(sizeof(value));
value_init_boolean(val, equals, expr_val->lineno);
vm_push_value(self, val);
value_free(type_val); free(type_val);
value_free(expr_val); free(expr_val);
self->pc++;
}

View File

@ -90,4 +90,6 @@ void vm_store(vm* self, int param);
void vm_load(vm* self, int param);
void vm_astore(vm* self, int param);
void vm_teq(vm* self);
#endif

16
tests/test_is.wuz Normal file
View File

@ -0,0 +1,16 @@
assert 5 is int
assert 5.9 is float
assert false is bool
assert "salut" is str
assert !(5 is float)
assert !(5.9 is bool)
assert !(false is str)
assert !("salut" is int)
assert [2, 4, 6] is array<int>
assert [[2, 4], [7, 9]] is array<array<int>>
assert int is type
assert type is type
assert (5.2 is int) is bool