ADD: 'is' keyword to test an expression against a type.
parent
76497315da
commit
9bb5a60b2a
|
@ -60,6 +60,11 @@ void compile_node(compiler* self, node* root, program* prog)
|
||||||
free(ty);
|
free(ty);
|
||||||
cstatic_free(&cs);
|
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)
|
else if (root->type == NODE_VARDECL)
|
||||||
{
|
{
|
||||||
cstatic cs;
|
cstatic cs;
|
||||||
|
@ -463,6 +468,11 @@ type* compile_get_type(compiler* self, node* root)
|
||||||
type_init(ty, TY_BOOLEAN);
|
type_init(ty, TY_BOOLEAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (strcmp(root->value, "type") == 0)
|
||||||
|
{
|
||||||
|
type_init(ty, TY_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
else if (strcmp(root->value, "array") == 0)
|
else if (strcmp(root->value, "array") == 0)
|
||||||
{
|
{
|
||||||
type_init(ty, TY_ARRAY);
|
type_init(ty, TY_ARRAY);
|
||||||
|
|
|
@ -201,7 +201,8 @@ type* cstatic_resolve_new(cstatic* self, symtable* sym, node* ast)
|
||||||
|| ast->type == NODE_GT
|
|| ast->type == NODE_GT
|
||||||
|| ast->type == NODE_GE
|
|| ast->type == NODE_GE
|
||||||
|| ast->type == NODE_EQ
|
|| ast->type == NODE_EQ
|
||||||
|| ast->type == NODE_NE)
|
|| ast->type == NODE_NE
|
||||||
|
|| ast->type == NODE_IS)
|
||||||
|
|
||||||
{
|
{
|
||||||
return cstatic_new_type(self, TY_BOOLEAN);
|
return cstatic_new_type(self, TY_BOOLEAN);
|
||||||
|
|
|
@ -13,7 +13,7 @@ BOOLEAN true|false
|
||||||
INTEGER -?[0-9]+
|
INTEGER -?[0-9]+
|
||||||
FLOAT -?[0-9]+\.[0-9]+
|
FLOAT -?[0-9]+\.[0-9]+
|
||||||
STRING \"[^"]*\"
|
STRING \"[^"]*\"
|
||||||
TYPE (int|float|bool|str|array)
|
TYPE (int|float|bool|str|array|type)
|
||||||
IDENT [_A-Za-z][_A-Za-z0-9]*
|
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);
|
yylval.str = str_new(yytext);
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
"is" { return IS; }
|
||||||
"do" { return DO; }
|
"do" { return DO; }
|
||||||
"end" { return END; }
|
"end" { return END; }
|
||||||
"let!" { return LET_MUT; }
|
"let!" { return LET_MUT; }
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
G(NODE_MUL), G(NODE_DIV), G(NODE_MOD), G(NODE_POW), \
|
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_ARRAY), G(NODE_INDEX), G(NODE_LT), G(NODE_LE), \
|
||||||
G(NODE_GT), G(NODE_GE), G(NODE_VARDECL), G(NODE_IDENT), \
|
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"
|
#include "mutils.h"
|
||||||
|
|
|
@ -44,7 +44,8 @@
|
||||||
G(OP_FGE), \
|
G(OP_FGE), \
|
||||||
G(OP_STORE), \
|
G(OP_STORE), \
|
||||||
G(OP_LOAD), \
|
G(OP_LOAD), \
|
||||||
G(OP_ASTORE)
|
G(OP_ASTORE), \
|
||||||
|
G(OP_TEQ)
|
||||||
|
|
||||||
|
|
||||||
enum Opcodes {
|
enum Opcodes {
|
||||||
|
|
18
src/parser.y
18
src/parser.y
|
@ -37,6 +37,7 @@
|
||||||
%token OSQUARE CSQUARE COMMA
|
%token OSQUARE CSQUARE COMMA
|
||||||
%token LET LET_MUT ASSIGN DO END
|
%token LET LET_MUT ASSIGN DO END
|
||||||
%type <n_children> expr_unop
|
%type <n_children> expr_unop
|
||||||
|
%left IS
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
@ -78,8 +79,23 @@ exprs:
|
||||||
|
|
||||||
|
|
||||||
expr:
|
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
|
// BLOCK
|
||||||
DO exprs END {
|
| DO exprs END {
|
||||||
node* n = malloc(sizeof(node));
|
node* n = malloc(sizeof(node));
|
||||||
node_init(n, NODE_DO, "", line);
|
node_init(n, NODE_DO, "", line);
|
||||||
|
|
||||||
|
|
24
src/vm.c
24
src/vm.c
|
@ -104,6 +104,8 @@ void vm_exec(vm* self, program* prog)
|
||||||
case OP_STORE: vm_store(self, param); break;
|
case OP_STORE: vm_store(self, param); break;
|
||||||
case OP_ASTORE: vm_astore(self, param); break;
|
case OP_ASTORE: vm_astore(self, param); break;
|
||||||
|
|
||||||
|
case OP_TEQ: vm_teq(self); break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
fprintf(stderr, "unknown opcode %s\n",
|
fprintf(stderr, "unknown opcode %s\n",
|
||||||
OpcodesStr[opcode]);
|
OpcodesStr[opcode]);
|
||||||
|
@ -1093,3 +1095,25 @@ void vm_astore(vm* self, int param)
|
||||||
self->pc++;
|
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++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
2
src/vm.h
2
src/vm.h
|
@ -90,4 +90,6 @@ void vm_store(vm* self, int param);
|
||||||
void vm_load(vm* self, int param);
|
void vm_load(vm* self, int param);
|
||||||
void vm_astore(vm* self, int param);
|
void vm_astore(vm* self, int param);
|
||||||
|
|
||||||
|
void vm_teq(vm* self);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue