Compare commits
No commits in common. "7847fe4c5dd98fa94ea47e4988e6cfbf9af4c28a" and "8317634e0641d37b8b9991ef0bf0cc4f3b3ce881" have entirely different histories.
7847fe4c5d
...
8317634e06
|
@ -2,8 +2,6 @@ ROOT ::= ATOM*
|
||||||
EXPR ::=
|
EXPR ::=
|
||||||
| ATOM
|
| ATOM
|
||||||
| CALL
|
| CALL
|
||||||
| ARRAY
|
|
||||||
ARRAY ::= osquare EXPR* csquare
|
|
||||||
CALL ::= opar EXPR EXPR* cpar
|
CALL ::= opar EXPR EXPR* cpar
|
||||||
ATOM ::=
|
ATOM ::=
|
||||||
| int
|
| int
|
||||||
|
|
|
@ -23,7 +23,6 @@ add_library(moka-core
|
||||||
module.c
|
module.c
|
||||||
path.c
|
path.c
|
||||||
builtins.c
|
builtins.c
|
||||||
array.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_options(moka-core
|
target_compile_options(moka-core
|
||||||
|
|
22
lib/array.c
22
lib/array.c
|
@ -1,22 +0,0 @@
|
||||||
#include "array.h"
|
|
||||||
#include "value.h"
|
|
||||||
|
|
||||||
void array_init(struct array* self)
|
|
||||||
{
|
|
||||||
assert(self);
|
|
||||||
vec_init(&self->values);
|
|
||||||
}
|
|
||||||
|
|
||||||
void array_free(struct array* self)
|
|
||||||
{
|
|
||||||
assert(self);
|
|
||||||
vec_free(&self->values);
|
|
||||||
}
|
|
||||||
|
|
||||||
void array_push_value(struct array* self, MOKA value)
|
|
||||||
{
|
|
||||||
assert(self);
|
|
||||||
assert(value);
|
|
||||||
|
|
||||||
vec_push(&self->values, (void*) value);
|
|
||||||
}
|
|
20
lib/array.h
20
lib/array.h
|
@ -1,20 +0,0 @@
|
||||||
#ifndef MK_ARRAY_H
|
|
||||||
#define MK_ARRAY_H
|
|
||||||
|
|
||||||
#include "commons.h"
|
|
||||||
#include "vec.h"
|
|
||||||
|
|
||||||
struct value;
|
|
||||||
|
|
||||||
struct array
|
|
||||||
{
|
|
||||||
struct vec values;
|
|
||||||
};
|
|
||||||
|
|
||||||
void array_init(struct array* self);
|
|
||||||
void array_free(struct array* self);
|
|
||||||
|
|
||||||
void array_push_value(struct array* self, MOKA value);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ void register_builtins(struct moka* moka)
|
||||||
assert(moka);
|
assert(moka);
|
||||||
moka_decl_native(moka, "println", mk_println);
|
moka_decl_native(moka, "println", mk_println);
|
||||||
moka_decl_native(moka, "define", mk_define);
|
moka_decl_native(moka, "define", mk_define);
|
||||||
moka_decl_native(moka, "array", mk_array);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MOKA mk_println(struct moka* moka, struct vec* args)
|
MOKA mk_println(struct moka* moka, struct vec* args)
|
||||||
|
@ -47,20 +46,3 @@ MOKA mk_define(struct moka* moka, struct vec* args)
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOKA mk_array(struct moka* moka, struct vec* args)
|
|
||||||
{
|
|
||||||
assert(moka);
|
|
||||||
assert(args);
|
|
||||||
|
|
||||||
for (size_t i=0; i<args->size; i++)
|
|
||||||
{
|
|
||||||
MOKA arg = (MOKA) args->data[i];
|
|
||||||
MOKA val = MK_EVAL(arg);
|
|
||||||
moka_push(moka, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
moka_make_array(moka, args->size);
|
|
||||||
|
|
||||||
return moka_top(moka);
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,6 +10,5 @@ void register_builtins(struct moka* moka);
|
||||||
|
|
||||||
MOKA mk_println(struct moka* moka, struct vec* args);
|
MOKA mk_println(struct moka* moka, struct vec* args);
|
||||||
MOKA mk_define(struct moka* moka, struct vec* args);
|
MOKA mk_define(struct moka* moka, struct vec* args);
|
||||||
MOKA mk_array(struct moka* moka, struct vec* args);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -36,14 +36,6 @@ void compiler_compile(struct compiler* self,
|
||||||
case NODE_CALL: {
|
case NODE_CALL: {
|
||||||
struct node* child = node->children.data[0];
|
struct node* child = node->children.data[0];
|
||||||
|
|
||||||
if (strcmp(child->token->value, "quote") == 0)
|
|
||||||
{
|
|
||||||
assert(node->children.size == 2);
|
|
||||||
struct node* arg = node->children.data[1];
|
|
||||||
compiler_quote(self, arg, prog, moka);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(child->token->value, "import") == 0)
|
if (strcmp(child->token->value, "import") == 0)
|
||||||
{
|
{
|
||||||
compiler_import(self, moka, node);
|
compiler_import(self, moka, node);
|
||||||
|
@ -231,40 +223,3 @@ void compiler_import(struct compiler* self,
|
||||||
name
|
name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void compiler_quote(struct compiler* self,
|
|
||||||
struct node* node,
|
|
||||||
struct prog* prog,
|
|
||||||
struct moka* moka)
|
|
||||||
{
|
|
||||||
assert(self);
|
|
||||||
assert(node);
|
|
||||||
assert(prog);
|
|
||||||
assert(moka);
|
|
||||||
|
|
||||||
switch (node->kind)
|
|
||||||
{
|
|
||||||
case NODE_INT: {
|
|
||||||
compiler_compile(self, node, prog, moka);
|
|
||||||
} break;
|
|
||||||
case NODE_IDENT: {
|
|
||||||
node->kind = NODE_SYMBOL;
|
|
||||||
compiler_compile(self, node, prog, moka);
|
|
||||||
} break;
|
|
||||||
case NODE_CALL: {
|
|
||||||
for (size_t i=0; i<node->children.size; i++)
|
|
||||||
{
|
|
||||||
compiler_quote(self, node->children.data[i],
|
|
||||||
prog, moka);
|
|
||||||
}
|
|
||||||
|
|
||||||
prog_add_instruction(prog, OP_MAKE_ARRAY,
|
|
||||||
node->children.size);
|
|
||||||
} break;
|
|
||||||
default: {
|
|
||||||
fprintf(stderr, "cannot quote node <%s>\n",
|
|
||||||
NodeKindStr[node->kind]);
|
|
||||||
abort();
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -25,9 +25,4 @@ void compiler_import(struct compiler* self,
|
||||||
struct moka* moka,
|
struct moka* moka,
|
||||||
struct node* node);
|
struct node* node);
|
||||||
|
|
||||||
void compiler_quote(struct compiler* self,
|
|
||||||
struct node* node,
|
|
||||||
struct prog* prog,
|
|
||||||
struct moka* moka);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,11 +37,6 @@ void exec_instr(struct exec* self,
|
||||||
|
|
||||||
switch (instr->opcode)
|
switch (instr->opcode)
|
||||||
{
|
{
|
||||||
case OP_MAKE_ARRAY: {
|
|
||||||
moka_make_array(moka, param);
|
|
||||||
self->pc++;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case OP_CALL: {
|
case OP_CALL: {
|
||||||
moka_call(moka, param);
|
moka_call(moka, param);
|
||||||
self->pc++;
|
self->pc++;
|
||||||
|
|
33
lib/lexer.c
33
lib/lexer.c
|
@ -19,8 +19,6 @@ void lexer_init(struct lexer* self,
|
||||||
str_init(&self->separators);
|
str_init(&self->separators);
|
||||||
str_push(&self->separators, '(');
|
str_push(&self->separators, '(');
|
||||||
str_push(&self->separators, ')');
|
str_push(&self->separators, ')');
|
||||||
str_push(&self->separators, '[');
|
|
||||||
str_push(&self->separators, ']');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lexer_free(struct lexer* self)
|
void lexer_free(struct lexer* self)
|
||||||
|
@ -35,23 +33,12 @@ struct token* lexer_try_new_next(struct lexer* self)
|
||||||
assert(self);
|
assert(self);
|
||||||
struct token* tok = NULL;
|
struct token* tok = NULL;
|
||||||
|
|
||||||
if (!status_is_ok(self->status))
|
if (!status_is_ok(self->status) > 0)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer_skip_spaces(self);
|
lexer_skip_spaces(self);
|
||||||
lexer_skip_comments(self);
|
|
||||||
|
|
||||||
if ( (tok=lexer_try_new_text(self, TOKEN_OSQUARE, "[")) )
|
|
||||||
{
|
|
||||||
return tok;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (tok=lexer_try_new_text(self, TOKEN_CSQUARE, "]")) )
|
|
||||||
{
|
|
||||||
return tok;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (tok=lexer_try_new_text(self, TOKEN_OPAR, "(")) )
|
if ( (tok=lexer_try_new_text(self, TOKEN_OPAR, "(")) )
|
||||||
{
|
{
|
||||||
|
@ -160,23 +147,6 @@ void lexer_skip_spaces(struct lexer* self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lexer_skip_comments(struct lexer* self)
|
|
||||||
{
|
|
||||||
assert(self);
|
|
||||||
|
|
||||||
while (self->context.cursor < self->len
|
|
||||||
&& self->source[self->context.cursor] == ';')
|
|
||||||
{
|
|
||||||
while (self->context.cursor < self->len
|
|
||||||
&& self->source[self->context.cursor] != '\n')
|
|
||||||
{
|
|
||||||
self->context.cursor++;
|
|
||||||
}
|
|
||||||
|
|
||||||
lexer_skip_spaces(self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct token* lexer_try_new_int(struct lexer* self)
|
struct token* lexer_try_new_int(struct lexer* self)
|
||||||
{
|
{
|
||||||
assert(self);
|
assert(self);
|
||||||
|
@ -557,6 +527,5 @@ bool lexer_end(struct lexer* self)
|
||||||
{
|
{
|
||||||
assert(self);
|
assert(self);
|
||||||
lexer_skip_spaces(self);
|
lexer_skip_spaces(self);
|
||||||
lexer_skip_comments(self);
|
|
||||||
return self->context.cursor >= self->len;
|
return self->context.cursor >= self->len;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ void lexer_free(struct lexer* self);
|
||||||
struct token* lexer_try_new_next(struct lexer* self);
|
struct token* lexer_try_new_next(struct lexer* self);
|
||||||
void lexer_skip(struct lexer* self, TokenKind kind);
|
void lexer_skip(struct lexer* self, TokenKind kind);
|
||||||
void lexer_skip_spaces(struct lexer* self);
|
void lexer_skip_spaces(struct lexer* self);
|
||||||
void lexer_skip_comments(struct lexer* self);
|
|
||||||
|
|
||||||
struct token* lexer_try_new_int(struct lexer* self);
|
struct token* lexer_try_new_int(struct lexer* self);
|
||||||
struct token* lexer_try_new_float(struct lexer* self);
|
struct token* lexer_try_new_float(struct lexer* self);
|
||||||
|
|
59
lib/moka.c
59
lib/moka.c
|
@ -246,28 +246,7 @@ void moka_dump(struct moka* self, MOKA value)
|
||||||
{
|
{
|
||||||
if (moka_is(self, value, TY_REF))
|
if (moka_is(self, value, TY_REF))
|
||||||
{
|
{
|
||||||
size_t ref = moka_get_ref(self, value);
|
printf("&%zu", moka_get_ref(self, value));
|
||||||
struct value* val = self->global_values.data[ref];
|
|
||||||
|
|
||||||
if (val->type == TY_ARRAY)
|
|
||||||
{
|
|
||||||
printf("[");
|
|
||||||
for (size_t i=0; i<val->data.array->values.size; i++)
|
|
||||||
{
|
|
||||||
if (i > 0) { printf(" "); }
|
|
||||||
MOKA v = (MOKA) val->data.array->values.data[i];
|
|
||||||
moka_dump(self, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("]");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char buffer[MK_STRLEN];
|
|
||||||
value_str(val, buffer, MK_STRLEN);
|
|
||||||
|
|
||||||
printf("%s", buffer);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,7 +276,7 @@ void moka_dump(struct moka* self, MOKA value)
|
||||||
|
|
||||||
if (moka_is(self, value, TY_SYMBOL))
|
if (moka_is(self, value, TY_SYMBOL))
|
||||||
{
|
{
|
||||||
printf("%s", moka_get_symbol(self, value));
|
printf("'%s", moka_get_symbol(self, value));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,40 +287,6 @@ void moka_dump(struct moka* self, MOKA value)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
MOKA moka_make_array(struct moka* self, int elements_count)
|
|
||||||
{
|
|
||||||
struct value* value = malloc(sizeof(struct value));
|
|
||||||
struct vec elements;
|
|
||||||
vec_init(&elements);
|
|
||||||
int line = 0;
|
|
||||||
struct frame* frame = moka_frame(self);
|
|
||||||
|
|
||||||
for (int i=0; i<elements_count; i++)
|
|
||||||
{
|
|
||||||
MOKA val = moka_pop(self);
|
|
||||||
line = ((struct value*) frame->local_values.data[val])->line;
|
|
||||||
vec_push(&elements, (void*) val);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vec reverse;
|
|
||||||
vec_init(&reverse);
|
|
||||||
|
|
||||||
for (size_t i=0; i<elements.size; i++)
|
|
||||||
{
|
|
||||||
size_t k = elements.size - 1 - i;
|
|
||||||
vec_push(&reverse, elements.data[k]);
|
|
||||||
}
|
|
||||||
|
|
||||||
value_init_array(value, &reverse, line);
|
|
||||||
|
|
||||||
vec_push(&self->global_values, value);
|
|
||||||
moka_push_ref(self, self->global_values.size - 1, line);
|
|
||||||
|
|
||||||
vec_free(&elements);
|
|
||||||
vec_free(&reverse);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOKA moka_call(struct moka* self, int arg_count)
|
MOKA moka_call(struct moka* self, int arg_count)
|
||||||
{
|
{
|
||||||
MOKA fun = moka_pop(self);
|
MOKA fun = moka_pop(self);
|
||||||
|
|
|
@ -63,7 +63,6 @@ TypeKind moka_type_of(struct moka* self, MOKA value);
|
||||||
|
|
||||||
void moka_dump(struct moka* self, MOKA value);
|
void moka_dump(struct moka* self, MOKA value);
|
||||||
|
|
||||||
MOKA moka_make_array(struct moka* self, int elements_count);
|
|
||||||
MOKA moka_call(struct moka* self, int arg_count);
|
MOKA moka_call(struct moka* self, int arg_count);
|
||||||
|
|
||||||
MOKA moka_push(struct moka* self, MOKA value);
|
MOKA moka_push(struct moka* self, MOKA value);
|
||||||
|
|
53
lib/parser.c
53
lib/parser.c
|
@ -47,7 +47,6 @@ struct node* parser_try_new_root(struct parser* self)
|
||||||
while (!lexer_end(self->lexer))
|
while (!lexer_end(self->lexer))
|
||||||
{
|
{
|
||||||
struct node* expr = MK_TRY(parser_try_new_expr);
|
struct node* expr = MK_TRY(parser_try_new_expr);
|
||||||
|
|
||||||
if (!expr && !lexer_end(self->lexer))
|
if (!expr && !lexer_end(self->lexer))
|
||||||
{
|
{
|
||||||
node_free(root);
|
node_free(root);
|
||||||
|
@ -70,58 +69,9 @@ struct node* parser_try_new_expr(struct parser* self)
|
||||||
return MK_TRY(parser_try_new_call);
|
return MK_TRY(parser_try_new_call);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lexer_next_is(self->lexer, TOKEN_OSQUARE, 0))
|
|
||||||
{
|
|
||||||
return MK_TRY(parser_try_new_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
return MK_TRY(parser_try_new_atom);
|
return MK_TRY(parser_try_new_atom);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct node* parser_try_new_array(struct parser* self)
|
|
||||||
{
|
|
||||||
if (!lexer_next_is(self->lexer, TOKEN_OSQUARE, 0))
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
lexer_skip(self->lexer, TOKEN_OSQUARE);
|
|
||||||
|
|
||||||
struct node* array = malloc(sizeof(struct node));
|
|
||||||
node_init(array, NODE_CALL, NULL, self->lexer->context.line);
|
|
||||||
|
|
||||||
while (!lexer_next_is(self->lexer, TOKEN_CSQUARE, 0))
|
|
||||||
{
|
|
||||||
struct node* expr = MK_TRY(parser_try_new_expr);
|
|
||||||
|
|
||||||
if (!expr)
|
|
||||||
{
|
|
||||||
node_free(array); free(array);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
node_add_new_child(array, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!lexer_next_is(self->lexer, TOKEN_CSQUARE, 0))
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
lexer_skip(self->lexer, TOKEN_CSQUARE);
|
|
||||||
|
|
||||||
struct node* node = malloc(sizeof(struct node));
|
|
||||||
node_init(node, NODE_CALL, NULL, self->lexer->context.line);
|
|
||||||
|
|
||||||
struct node* ident = malloc(sizeof(struct node));
|
|
||||||
struct token* tok = malloc(sizeof(struct token));
|
|
||||||
token_init(tok, TOKEN_IDENT, "quote");
|
|
||||||
|
|
||||||
node_init(ident, NODE_IDENT, tok, self->lexer->context.line);
|
|
||||||
node_add_new_child(node, ident);
|
|
||||||
node_add_new_child(node, array);
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct node* parser_try_new_call(struct parser* self)
|
struct node* parser_try_new_call(struct parser* self)
|
||||||
{
|
{
|
||||||
assert(self);
|
assert(self);
|
||||||
|
@ -167,6 +117,7 @@ struct node* parser_try_new_call(struct parser* self)
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer_skip(self->lexer, TOKEN_CPAR);
|
lexer_skip(self->lexer, TOKEN_CPAR);
|
||||||
|
|
||||||
return call;
|
return call;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,8 +184,6 @@ struct node* parser_try_new_atom(struct parser* self)
|
||||||
self->lexer->context.line);
|
self->lexer->context.line);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ struct node* parser_try(struct parser* self,
|
||||||
|
|
||||||
struct node* parser_try_new_root(struct parser* self);
|
struct node* parser_try_new_root(struct parser* self);
|
||||||
struct node* parser_try_new_expr(struct parser* self);
|
struct node* parser_try_new_expr(struct parser* self);
|
||||||
struct node* parser_try_new_array(struct parser* self);
|
|
||||||
struct node* parser_try_new_call(struct parser* self);
|
struct node* parser_try_new_call(struct parser* self);
|
||||||
struct node* parser_try_new_atom(struct parser* self);
|
struct node* parser_try_new_atom(struct parser* self);
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,6 @@ size_t prog_add_instruction(struct prog* self,
|
||||||
self->stack_addr++;
|
self->stack_addr++;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case OP_MAKE_ARRAY: {
|
|
||||||
self->stack_addr += param;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
fprintf(stderr, "cannot find stack address of <%s>\n",
|
fprintf(stderr, "cannot find stack address of <%s>\n",
|
||||||
OpcodeKindStr[opcode]);
|
OpcodeKindStr[opcode]);
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
G(OP_PUSH), \
|
G(OP_PUSH), \
|
||||||
G(OP_LOCAL_LOAD), \
|
G(OP_LOCAL_LOAD), \
|
||||||
G(OP_GLOBAL_LOAD), \
|
G(OP_GLOBAL_LOAD), \
|
||||||
G(OP_CALL), \
|
G(OP_CALL)
|
||||||
G(OP_MAKE_ARRAY)
|
|
||||||
|
|
||||||
MK_ENUM_H(OpcodeKind, OPCODE_KIND);
|
MK_ENUM_H(OpcodeKind, OPCODE_KIND);
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,7 @@
|
||||||
G(TOKEN_INT), G(TOKEN_FLOAT), \
|
G(TOKEN_INT), G(TOKEN_FLOAT), \
|
||||||
G(TOKEN_BOOL), G(TOKEN_STRING), \
|
G(TOKEN_BOOL), G(TOKEN_STRING), \
|
||||||
G(TOKEN_SYMBOL), G(TOKEN_IDENT), \
|
G(TOKEN_SYMBOL), G(TOKEN_IDENT), \
|
||||||
G(TOKEN_OPAR), G(TOKEN_CPAR), \
|
G(TOKEN_OPAR), G(TOKEN_CPAR)
|
||||||
G(TOKEN_OSQUARE), G(TOKEN_CSQUARE)
|
|
||||||
|
|
||||||
MK_ENUM_H(TokenKind, TOKEN_KIND);
|
MK_ENUM_H(TokenKind, TOKEN_KIND);
|
||||||
|
|
||||||
|
|
89
lib/value.c
89
lib/value.c
|
@ -71,89 +71,6 @@ void value_init_lazy(struct value* self, struct node* value, int line)
|
||||||
self->line = line;
|
self->line = line;
|
||||||
}
|
}
|
||||||
|
|
||||||
void value_init_array(struct value* self, struct vec* new_values, int line)
|
|
||||||
{
|
|
||||||
assert(self);
|
|
||||||
assert(new_values);
|
|
||||||
|
|
||||||
self->data.array = malloc(sizeof(struct array));
|
|
||||||
array_init(self->data.array);
|
|
||||||
|
|
||||||
for (size_t i=0; i<new_values->size; i++)
|
|
||||||
{
|
|
||||||
array_push_value(self->data.array, (MOKA) new_values->data[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
self->type = TY_ARRAY;
|
|
||||||
self->line = line;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t value_str(struct value* self, char* buffer, size_t size)
|
|
||||||
{
|
|
||||||
assert(self);
|
|
||||||
assert(buffer);
|
|
||||||
|
|
||||||
switch (self->type)
|
|
||||||
{
|
|
||||||
case TY_INT: {
|
|
||||||
return snprintf(buffer, size, "%d", self->data.integer);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case TY_FLOAT: {
|
|
||||||
return snprintf(buffer, size, "%f", self->data.real);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case TY_BOOL: {
|
|
||||||
return snprintf(buffer, size, "%s",
|
|
||||||
self->data.boolean ? "true" : "false");
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case TY_STRING: {
|
|
||||||
return snprintf(buffer, size, "%s", self->data.str);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case TY_SYMBOL: {
|
|
||||||
return snprintf(buffer, size, "%s", self->data.sym);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case TY_REF: {
|
|
||||||
return snprintf(buffer, size, "<ref:%zu>", self->data.ref);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case TY_NATIVE: {
|
|
||||||
return snprintf(buffer, size, "<native: %p>", self->data.native);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case TY_LAZY: {
|
|
||||||
return snprintf(buffer, size, "<lazy:%s>",
|
|
||||||
NodeKindStr[self->data.lazy->kind]
|
|
||||||
+ strlen("NODE_"));
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case TY_ARRAY: {
|
|
||||||
size_t sz = 0;
|
|
||||||
sz += snprintf(buffer + sz, size - sz, "[array]");
|
|
||||||
return sz;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: {
|
|
||||||
fprintf(stderr, "cannot stringify value <%s>\n",
|
|
||||||
TypeKindStr[self->type]);
|
|
||||||
abort();
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// void value_init_int(struct value* self, int value, int line);
|
|
||||||
// void value_init_float(struct value* self, float value, int line);
|
|
||||||
// void value_init_bool(struct value* self, bool value, int line);
|
|
||||||
// void value_init_string(struct value* self, char const* value, int line);
|
|
||||||
// void value_init_symbol(struct value* self, char const* value, int line);
|
|
||||||
// void value_init_ref(struct value* self, size_t value, int line);
|
|
||||||
// void value_init_native(struct value* self, struct native* value, int line);
|
|
||||||
// void value_init_lazy(struct value* self, struct node* value, int line);
|
|
||||||
// void value_init_array(struct value* self, struct vec* new_values, int line);
|
|
||||||
}
|
|
||||||
|
|
||||||
void value_free(struct value* self)
|
void value_free(struct value* self)
|
||||||
{
|
{
|
||||||
assert(self);
|
assert(self);
|
||||||
|
@ -173,10 +90,4 @@ void value_free(struct value* self)
|
||||||
native_free(self->data.native);
|
native_free(self->data.native);
|
||||||
free(self->data.native);
|
free(self->data.native);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->type == TY_ARRAY)
|
|
||||||
{
|
|
||||||
array_free(self->data.array);
|
|
||||||
free(self->data.array);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,11 @@
|
||||||
|
|
||||||
#include "commons.h"
|
#include "commons.h"
|
||||||
#include "native.h"
|
#include "native.h"
|
||||||
#include "array.h"
|
|
||||||
|
|
||||||
#define TYPE_KIND(G) \
|
#define TYPE_KIND(G) \
|
||||||
G(TY_INT), G(TY_FLOAT), G(TY_BOOL), \
|
G(TY_INT), G(TY_FLOAT), G(TY_BOOL), \
|
||||||
G(TY_STRING), G(TY_SYMBOL), G(TY_REF), \
|
G(TY_STRING), G(TY_SYMBOL), G(TY_REF), \
|
||||||
G(TY_NATIVE), G(TY_LAZY), G(TY_ARRAY)
|
G(TY_NATIVE), G(TY_LAZY)
|
||||||
|
|
||||||
MK_ENUM_H(TypeKind, TYPE_KIND);
|
MK_ENUM_H(TypeKind, TYPE_KIND);
|
||||||
|
|
||||||
|
@ -22,7 +21,6 @@ union value_data
|
||||||
size_t ref;
|
size_t ref;
|
||||||
struct native* native;
|
struct native* native;
|
||||||
struct node* lazy;
|
struct node* lazy;
|
||||||
struct array* array;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct value
|
struct value
|
||||||
|
@ -40,9 +38,6 @@ void value_init_symbol(struct value* self, char const* value, int line);
|
||||||
void value_init_ref(struct value* self, size_t value, int line);
|
void value_init_ref(struct value* self, size_t value, int line);
|
||||||
void value_init_native(struct value* self, struct native* value, int line);
|
void value_init_native(struct value* self, struct native* value, int line);
|
||||||
void value_init_lazy(struct value* self, struct node* value, int line);
|
void value_init_lazy(struct value* self, struct node* value, int line);
|
||||||
void value_init_array(struct value* self, struct vec* new_values, int line);
|
|
||||||
|
|
||||||
size_t value_str(struct value* self, char* buffer, size_t size);
|
|
||||||
|
|
||||||
void value_free(struct value* self);
|
void value_free(struct value* self);
|
||||||
|
|
||||||
|
|
|
@ -84,22 +84,11 @@ START_TEST(lexer_funcall)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
START_TEST(lexer_array)
|
|
||||||
{
|
|
||||||
test_lexer(" [] ", 2,
|
|
||||||
TOKEN_OSQUARE, "[",
|
|
||||||
TOKEN_CSQUARE, "]"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
END_TEST
|
|
||||||
|
|
||||||
void register_lexer(Suite* suite)
|
void register_lexer(Suite* suite)
|
||||||
{
|
{
|
||||||
TCase* tcase = tcase_create("Lexer");
|
TCase* tcase = tcase_create("Lexer");
|
||||||
tcase_add_test(tcase, lexer_atom);
|
tcase_add_test(tcase, lexer_atom);
|
||||||
tcase_add_test(tcase, lexer_funcall);
|
tcase_add_test(tcase, lexer_funcall);
|
||||||
tcase_add_test(tcase, lexer_array);
|
|
||||||
suite_add_tcase(suite, tcase);
|
suite_add_tcase(suite, tcase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,22 +72,11 @@ START_TEST(parser_call)
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
START_TEST(parser_array)
|
|
||||||
{
|
|
||||||
test_parser("ROOT(CALL(IDENT[quote],CALL(INT[1],INT[2],INT[3])))",
|
|
||||||
" [1 2 3] ");
|
|
||||||
|
|
||||||
test_parser("ROOT(CALL(IDENT[quote],CALL(INT[1])))",
|
|
||||||
" [1] ");
|
|
||||||
}
|
|
||||||
END_TEST
|
|
||||||
|
|
||||||
void register_parser(Suite* suite)
|
void register_parser(Suite* suite)
|
||||||
{
|
{
|
||||||
TCase* tcase = tcase_create("Parser");
|
TCase* tcase = tcase_create("Parser");
|
||||||
tcase_add_test(tcase, parser_atom);
|
tcase_add_test(tcase, parser_atom);
|
||||||
tcase_add_test(tcase, parser_call);
|
tcase_add_test(tcase, parser_call);
|
||||||
tcase_add_test(tcase, parser_array);
|
|
||||||
|
|
||||||
suite_add_tcase(suite, tcase);
|
suite_add_tcase(suite, tcase);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue