Compare commits

..

No commits in common. "6013d65776c485a6629e1dbc85b67e2ab5c5265b" and "32c0bb83528d33b08be0a60d77bb61a76b116e6a" have entirely different histories.

22 changed files with 54 additions and 642 deletions

View File

@ -1,7 +1,6 @@
#ifndef COMMONS_H #ifndef COMMONS_H
#define COMMON_H #define COMMON_H
#include <stdarg.h>
#include <math.h> #include <math.h>
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>

View File

@ -1,5 +1,4 @@
#include "compiler.h" #include "compiler.h"
#include "cstatic.h"
void compiler_init(compiler* self) void compiler_init(compiler* self)
{ {
@ -17,54 +16,7 @@ void compile_node(compiler* self, node* root, program* prog)
assert(root); assert(root);
assert(prog); assert(prog);
if (root->type == NODE_MUL) if (root->type == NODE_BOOLEAN)
{
cstatic cs;
cstatic_init(&cs);
int lhs = cstatic_resolve(&cs, root->children.data[0]);
int rhs = cstatic_resolve(&cs, root->children.data[1]);
cstatic_free(&cs);
if (lhs == TY_INTEGER && rhs == TY_STRING)
{
compile_node(self, root->children.data[0], prog);
compile_node(self, root->children.data[1], prog);
program_add_instr(prog, OP_SMUL, NO_PARAM);
}
else if (lhs == TY_STRING && rhs == TY_INTEGER)
{
compile_node(self, root->children.data[1], prog);
compile_node(self, root->children.data[0], prog);
program_add_instr(prog, OP_SMUL, NO_PARAM);
}
else
{
compile_number(self, root, prog, OP_IMUL, OP_FMUL);
}
}
else if (root->type == NODE_ADD)
{
cstatic cs;
cstatic_init(&cs);
int lhs = cstatic_resolve(&cs, root->children.data[0]);
int rhs = cstatic_resolve(&cs, root->children.data[1]);
cstatic_free(&cs);
if (lhs == rhs && lhs == TY_STRING)
{
compile_children(self, root, prog);
program_add_instr(prog, OP_CAT, NO_PARAM);
}
else
{
compile_number(self, root, prog, OP_IADD, OP_FADD);
}
}
else if (root->type == NODE_BOOLEAN)
{ {
value val; value val;
value_init_boolean(&val, value_init_boolean(&val,
@ -74,26 +26,6 @@ void compile_node(compiler* self, node* root, program* prog)
program_add_instr(prog, OP_PUSH, idx); program_add_instr(prog, OP_PUSH, idx);
value_free(&val); value_free(&val);
} }
else if (root->type == NODE_FLOAT)
{
value val;
value_init_float(&val,
atof(root->value),
root->lineno);
size_t idx = program_add_pool(prog, &val);
program_add_instr(prog, OP_PUSH, idx);
value_free(&val);
}
else if (root->type == NODE_STRING)
{
value val;
value_init_string(&val,
root->value,
root->lineno);
size_t idx = program_add_pool(prog, &val);
program_add_instr(prog, OP_PUSH, idx);
value_free(&val);
}
else if (root->type == NODE_INTEGER) else if (root->type == NODE_INTEGER)
{ {
value val; value val;
@ -111,31 +43,43 @@ void compile_node(compiler* self, node* root, program* prog)
} }
else if (root->type == NODE_UADD) else if (root->type == NODE_UADD)
{ {
compile_number(self, root, prog, OP_IUADD, OP_FUADD); compile_children(self, root, prog);
program_add_instr(prog, OP_IUADD, NO_PARAM);
} }
else if (root->type == NODE_USUB) else if (root->type == NODE_USUB)
{ {
compile_number(self, root, prog, OP_IUSUB, OP_FUSUB); compile_children(self, root, prog);
program_add_instr(prog, OP_IUSUB, NO_PARAM);
}
else if (root->type == NODE_ADD)
{
compile_children(self, root, prog);
program_add_instr(prog, OP_IADD, NO_PARAM);
} }
else if (root->type == NODE_SUB) else if (root->type == NODE_SUB)
{ {
compile_number(self, root, prog, OP_ISUB, OP_FSUB); compile_children(self, root, prog);
program_add_instr(prog, OP_ISUB, NO_PARAM);
} }
else if (root->type == NODE_MUL) else if (root->type == NODE_MUL)
{ {
compile_number(self, root, prog, OP_IMUL, OP_FMUL); compile_children(self, root, prog);
program_add_instr(prog, OP_IMUL, NO_PARAM);
} }
else if (root->type == NODE_DIV) else if (root->type == NODE_DIV)
{ {
compile_number(self, root, prog, OP_IDIV, OP_FDIV); compile_children(self, root, prog);
program_add_instr(prog, OP_IDIV, NO_PARAM);
} }
else if (root->type == NODE_MOD) else if (root->type == NODE_MOD)
{ {
compile_number(self, root, prog, OP_IMOD, OP_FMOD); compile_children(self, root, prog);
program_add_instr(prog, OP_IMOD, NO_PARAM);
} }
else if (root->type == NODE_POW) else if (root->type == NODE_POW)
{ {
compile_number(self, root, prog, OP_IPOW, OP_FPOW); compile_children(self, root, prog);
program_add_instr(prog, OP_IPOW, NO_PARAM);
} }
else if (root->type == NODE_EQ) else if (root->type == NODE_EQ)
{ {
@ -180,35 +124,3 @@ void compile_children(compiler* self, node* root, program* prog)
compile_node(self, root->children.data[i], prog); compile_node(self, root->children.data[i], prog);
} }
} }
void compile_number(compiler* self, node* root, program* prog,
int integer_op,
int float_op)
{
compile_children(self, root, prog);
cstatic cs;
cstatic_init(&cs);
int ty = cstatic_resolve(&cs, root);
switch (ty)
{
case TY_INTEGER:
program_add_instr(prog, integer_op, NO_PARAM);
break;
case TY_FLOAT:
program_add_instr(prog, float_op, NO_PARAM);
break;
default:
fprintf(stderr, "E(%d): cannot add type '%s'.",
root->lineno,
TypesStr[ty]);
exit(-1);
break;
}
cstatic_free(&cs);
}

View File

@ -15,7 +15,4 @@ void compiler_free(compiler* self);
void compile_node(compiler* self, node* root, program* prog); void compile_node(compiler* self, node* root, program* prog);
void compile_children(compiler* self, node* root, program* prog); void compile_children(compiler* self, node* root, program* prog);
void compile_number(compiler* self, node* root, program* prog,
int integer_op,
int float_op);
#endif #endif

View File

@ -16,44 +16,10 @@ int cstatic_resolve(cstatic* self, node* ast)
assert(self); assert(self);
assert(ast); assert(ast);
if (ast->type == NODE_MUL)
{
int lhs = cstatic_resolve(self, ast->children.data[0]);
int rhs = cstatic_resolve(self, ast->children.data[1]);
if (lhs == TY_STRING || rhs == TY_STRING)
{
return TY_STRING;
}
}
if (ast->type == NODE_INTEGER) if (ast->type == NODE_INTEGER)
{ {
return TY_INTEGER; return TY_INTEGER;
} }
else if (ast->type == NODE_FLOAT)
{
return TY_FLOAT;
}
else if (ast->type == NODE_ADD)
{
int lhs = cstatic_resolve(self, ast->children.data[0]);
int rhs = cstatic_resolve(self, ast->children.data[1]);
if (lhs == TY_STRING && rhs == TY_STRING)
{
return TY_STRING;
}
return lhs;
}
else if (ast->type == NODE_STRING)
{
return TY_STRING;
}
else if (ast->type == NODE_BOOLEAN else if (ast->type == NODE_BOOLEAN
|| ast->type == NODE_EQ || ast->type == NODE_EQ
|| ast->type == NODE_NE) || ast->type == NODE_NE)
@ -94,31 +60,6 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
} }
// String Operations
if (ast->type == NODE_ADD)
{
int lhs = cstatic_resolve(self, ast->children.data[0]);
int rhs = cstatic_resolve(self, ast->children.data[1]);
if (lhs == rhs && lhs == TY_STRING)
{
return 1;
}
}
if (ast->type == NODE_MUL)
{
int lhs = cstatic_resolve(self, ast->children.data[0]);
int rhs = cstatic_resolve(self, ast->children.data[1]);
if ((lhs == TY_STRING && rhs == TY_INTEGER)
|| (lhs == TY_INTEGER && rhs == TY_STRING))
{
return 1;
}
}
// Integer Binops // Integer Binops
if (ast->type == NODE_EQ if (ast->type == NODE_EQ
|| ast->type == NODE_NE) || ast->type == NODE_NE)
@ -141,10 +82,9 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
{ {
int status = cstatic_check_type(self, int status = cstatic_check_type(self,
ast->children.data[0], ast->children.data[0],
msg,
size,
TY_BOOLEAN, TY_BOOLEAN,
TYPE_END); msg,
size);
if (!status) if (!status)
{ {
@ -169,10 +109,9 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
status = cstatic_check_type(self, status = cstatic_check_type(self,
ast->children.data[0], ast->children.data[0],
msg,
size,
TY_BOOLEAN, TY_BOOLEAN,
TYPE_END); msg,
size);
if (!status) if (!status)
{ {
return status; return status;
@ -185,16 +124,15 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
{ {
int status = cstatic_check_type(self, int status = cstatic_check_type(self,
ast->children.data[0], ast->children.data[0],
msg,
size,
TY_INTEGER, TY_INTEGER,
TY_FLOAT, msg,
TYPE_END); size);
if (!status) if (!status)
{ {
return status; return status;
} }
} }
// Integer Binops // Integer Binops
else if (ast->type == NODE_ADD else if (ast->type == NODE_ADD
|| ast->type == NODE_SUB || ast->type == NODE_SUB
@ -217,11 +155,9 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
status = cstatic_check_type(self, status = cstatic_check_type(self,
ast->children.data[0], ast->children.data[0],
msg,
size,
TY_INTEGER, TY_INTEGER,
TY_FLOAT, msg,
TYPE_END); size);
if (!status) if (!status)
{ {
return status; return status;
@ -231,56 +167,24 @@ int cstatic_check(cstatic* self, node* ast, char* msg, size_t size)
return 1; return 1;
} }
int cstatic_check_type(cstatic* self, node* lhs, int cstatic_check_type(cstatic* self, node* lhs, int rhs,
char* msg, size_t size, int types, ...) char* msg, size_t size)
{ {
assert(self); assert(self);
assert(lhs); assert(lhs);
char aze[512];
node_str(lhs, aze, 512);
va_list args;
va_start(args, types);
int rhs = types;
int left = cstatic_resolve(self, lhs); int left = cstatic_resolve(self, lhs);
int all_types[TY_TYPE_COUNT]; if (left != rhs)
memset(all_types, TYPE_END, TY_TYPE_COUNT * sizeof(int));
size_t i = 0;
while (rhs != TYPE_END)
{ {
all_types[i] = rhs; snprintf(msg, size, "E(%d): expected '%s', got '%s'.",
if (left == rhs)
{
va_end(args);
return 1;
}
rhs = va_arg(args, int);
i++;
}
va_end(args);
size_t sz = snprintf(msg, size, "E(%d): type mismatch, got '%s', ",
lhs->lineno, lhs->lineno,
TypesStr[left]); TypesStr[left],
TypesStr[rhs]);
sz += snprintf(msg + sz, size - sz, "expected: \n"); return 0;
size_t j = 0;
while (all_types[j] != TYPE_END)
{
sz += snprintf(msg + sz, size - sz, "\t '%s'\n",
TypesStr[all_types[j]]);
j++;
} }
return 0; return 1;
} }
int cstatic_check_same_type(cstatic* self, node* lhs, node* rhs, int cstatic_check_same_type(cstatic* self, node* lhs, node* rhs,

View File

@ -4,8 +4,6 @@
#include "commons.h" #include "commons.h"
#include "node.h" #include "node.h"
#define TYPE_END (-1)
typedef struct { typedef struct {
int _unused; int _unused;
} cstatic; } cstatic;
@ -16,8 +14,8 @@ void cstatic_free(cstatic* self);
int cstatic_resolve(cstatic* self, node* ast); int cstatic_resolve(cstatic* self, node* ast);
int cstatic_check(cstatic* self, node* ast, char* msg, size_t size); int cstatic_check(cstatic* self, node* ast, char* msg, size_t size);
int cstatic_check_type(cstatic* self, node* lhs, int cstatic_check_type(cstatic* self, node* lhs, int rhs,
char* msg, size_t size, int types, ...); char* msg, size_t size);
int cstatic_check_same_type(cstatic* self, node* lhs, node* rhs, int cstatic_check_same_type(cstatic* self, node* lhs, node* rhs,
char* msg, size_t size); char* msg, size_t size);

View File

@ -11,8 +11,6 @@ COMMENT ::[^\n]*
WHITESPACES [ \t]+ WHITESPACES [ \t]+
BOOLEAN true|false BOOLEAN true|false
INTEGER -?[0-9]+ INTEGER -?[0-9]+
FLOAT -?[0-9]+\.[0-9]+
STRING \"[^\"]*\"
%% %%
"\n" { line++; } "\n" { line++; }
@ -40,16 +38,6 @@ STRING \"[^\"]*\"
return BOOLEAN; return BOOLEAN;
} }
{STRING} {
yylval.str = yytext;
return STRING;
}
{FLOAT} {
yylval.str = yytext;
return FLOAT;
}
{INTEGER} { {INTEGER} {
yylval.str = yytext; yylval.str = yytext;
return INTEGER; return INTEGER;

View File

@ -3,8 +3,7 @@
#define NODE_TYPE(G) \ #define NODE_TYPE(G) \
G(NODE_PROG), \ G(NODE_PROG), \
G(NODE_BOOLEAN), G(NODE_INTEGER), G(NODE_FLOAT), \ G(NODE_BOOLEAN), G(NODE_INTEGER), \
G(NODE_STRING), \
G(NODE_AND), G(NODE_OR), G(NODE_NOT), \ G(NODE_AND), G(NODE_OR), G(NODE_NOT), \
G(NODE_EQ), G(NODE_NE), \ G(NODE_EQ), G(NODE_NE), \
G(NODE_ASSERT), \ G(NODE_ASSERT), \

View File

@ -17,17 +17,7 @@
G(OP_IMOD), \ G(OP_IMOD), \
G(OP_IPOW), \ G(OP_IPOW), \
G(OP_IUADD), \ G(OP_IUADD), \
G(OP_IUSUB), \ G(OP_IUSUB),
G(OP_FADD), \
G(OP_FSUB), \
G(OP_FMUL), \
G(OP_FDIV), \
G(OP_FMOD), \
G(OP_FPOW), \
G(OP_FUADD), \
G(OP_FUSUB), \
G(OP_CAT), \
G(OP_SMUL)
enum Opcodes { enum Opcodes {
OPCODES(GEN_ENUM) OPCODES(GEN_ENUM)

View File

@ -22,7 +22,8 @@
}; };
%left ASSERT %left ASSERT
%token <str> BOOLEAN INTEGER FLOAT STRING %token <str> BOOLEAN
%token <str> INTEGER
%left EQ NE %left EQ NE
%left AND %left AND
%left OR %left OR
@ -166,16 +167,6 @@ expr:
$$ = $2; $$ = $2;
} }
| STRING {
node* n = malloc(sizeof(node));
size_t const SZ = strlen($1);
char str[SZ - 2];
memcpy(str, $1 + 1, SZ - 2);
str[SZ - 2] = '\0';
node_init(n, NODE_STRING, str, line);
$$ = n;
}
| BOOLEAN { | BOOLEAN {
node* n = malloc(sizeof(node)); node* n = malloc(sizeof(node));
@ -188,12 +179,6 @@ expr:
node_init(n, NODE_INTEGER, $1, line); node_init(n, NODE_INTEGER, $1, line);
$$ = n; $$ = n;
} }
| FLOAT {
node* n = malloc(sizeof(node));
node_init(n, NODE_FLOAT, $1, line);
$$ = n;
}
; ;
%% %%

View File

@ -6,10 +6,7 @@
#define TYPES(G) \ #define TYPES(G) \
G(TY_NIL), \ G(TY_NIL), \
G(TY_BOOLEAN), \ G(TY_BOOLEAN), \
G(TY_INTEGER), \ G(TY_INTEGER),
G(TY_FLOAT), \
G(TY_STRING), \
G(TY_TYPE_COUNT)
enum Types { enum Types {
TYPES(GEN_ENUM) TYPES(GEN_ENUM)

View File

@ -1,6 +1,6 @@
#include "utils.h" #include "utils.h"
char* str_new(char const* str) char const* str_new(char const* str)
{ {
size_t len = strlen(str) + 1; size_t len = strlen(str) + 1;

View File

@ -1,8 +1,7 @@
#ifndef UTILS_H #ifndef UTILS_H
#define UTILS_H #define UTILS_H
#include <string.h> #include <string.h>
#include <stdlib.h>
char* str_new(char const* str); char const* str_new(char const* str);
#endif #endif

View File

@ -20,39 +20,9 @@ void value_init_integer(value* self, int integer, int lineno)
type_init(self->type, TY_INTEGER); type_init(self->type, TY_INTEGER);
} }
void value_init_float(value* self, float real_float, int lineno)
{
assert(self);
self->val.real_float = real_float;
self->lineno = lineno;
self->type = malloc(sizeof(type));
type_init(self->type, TY_FLOAT);
}
void value_init_string(value* self, char* str, int lineno)
{
assert(self);
self->val.string = str_new(str);
self->lineno = lineno;
self->type = malloc(sizeof(type));
type_init(self->type, TY_STRING);
}
void value_free(value* self) void value_free(value* self)
{ {
assert(self); assert(self);
if (self->type->base_type == TY_STRING
&& self->val.string != NULL)
{
free(self->val.string);
self->val.string = NULL;
}
type_free(self->type); type_free(self->type);
free(self->type); free(self->type);
self->type = NULL; self->type = NULL;
@ -64,12 +34,6 @@ value* value_new_clone(value* self)
value* clone = malloc(sizeof(value)); value* clone = malloc(sizeof(value));
clone->type = type_new_clone(self->type); clone->type = type_new_clone(self->type);
clone->val = self->val; clone->val = self->val;
if (self->type->base_type == TY_STRING)
{
clone->val.string = str_new(self->val.string);
}
clone->lineno = self->lineno; clone->lineno = self->lineno;
return clone; return clone;
@ -96,16 +60,6 @@ int value_equals(value* self, value* rhs)
return self->val.integer == rhs->val.integer; return self->val.integer == rhs->val.integer;
} }
if (self->type->base_type == TY_FLOAT)
{
return self->val.real_float == rhs->val.real_float;
}
if (self->type->base_type == TY_STRING)
{
return strcmp(self->val.string, rhs->val.string) == 0;
}
size_t const SZ = 512; size_t const SZ = 512;
char ty_str[SZ]; char ty_str[SZ];
@ -126,9 +80,6 @@ size_t value_str(value* self, char* buffer, size_t size)
return snprintf(buffer, size, "%s", return snprintf(buffer, size, "%s",
self->val.boolean == 0 self->val.boolean == 0
? "false" : "true"); ? "false" : "true");
case TY_STRING:
return snprintf(buffer, size, "%s",
self->val.string);
case TY_INTEGER: case TY_INTEGER:
return snprintf(buffer, size, "%d", return snprintf(buffer, size, "%d",
self->val.integer); self->val.integer);

View File

@ -10,16 +10,11 @@ typedef struct {
union { union {
int boolean; int boolean;
int integer; int integer;
float real_float;
char* string;
} val; } val;
} value; } value;
void value_init_boolean(value* self, int boolean, int lineno); void value_init_boolean(value* self, int boolean, int lineno);
void value_init_integer(value* self, int integer, int lineno); void value_init_integer(value* self, int integer, int lineno);
void value_init_float(value* self, float real_float, int lineno);
void value_init_string(value* self, char* string, int lineno);
void value_free(value* self); void value_free(value* self);
value* value_new_clone(value* self); value* value_new_clone(value* self);

210
src/vm.c
View File

@ -54,21 +54,7 @@ void vm_exec(vm* self, program* prog)
case OP_IDIV: vm_idiv(self); break; case OP_IDIV: vm_idiv(self); break;
case OP_IMOD: vm_imod(self); break; case OP_IMOD: vm_imod(self); break;
case OP_IPOW: vm_ipow(self); break; case OP_IPOW: vm_ipow(self); break;
case OP_FADD: vm_fadd(self); break;
case OP_FUADD: vm_fuadd(self); break;
case OP_FSUB: vm_fsub(self); break;
case OP_FUSUB: vm_fusub(self); break;
case OP_FMUL: vm_fmul(self); break;
case OP_FDIV: vm_fdiv(self); break;
case OP_FMOD: vm_fmod(self); break;
case OP_FPOW: vm_fpow(self); break;
case OP_ASSERT: vm_assert(self); break; case OP_ASSERT: vm_assert(self); break;
case OP_SMUL: vm_smul(self); break;
case OP_CAT: vm_cat(self); break;
default: { default: {
fprintf(stderr, "unknown opcode %s\n", fprintf(stderr, "unknown opcode %s\n",
OpcodesStr[opcode]); OpcodesStr[opcode]);
@ -317,142 +303,6 @@ void vm_ipow(vm* self)
self->pc++; self->pc++;
} }
void vm_fadd(vm* self)
{
value* rhs = vm_pop_value(self);
value* lhs = vm_pop_value(self);
value* val = malloc(sizeof(value));
value_init_float(val, lhs->val.real_float
+ rhs->val.real_float, lhs->lineno);
vm_push_value(self, val);
value_free(rhs);
free(rhs);
value_free(lhs);
free(lhs);
self->pc++;
}
void vm_fuadd(vm* self)
{
value* lhs = vm_pop_value(self);
value* val = malloc(sizeof(value));
value_init_float(val, lhs->val.real_float, lhs->lineno);
vm_push_value(self, val);
value_free(lhs);
free(lhs);
self->pc++;
}
void vm_fsub(vm* self)
{
value* rhs = vm_pop_value(self);
value* lhs = vm_pop_value(self);
value* val = malloc(sizeof(value));
value_init_float(val, lhs->val.real_float
- rhs->val.real_float, lhs->lineno);
vm_push_value(self, val);
value_free(rhs);
free(rhs);
value_free(lhs);
free(lhs);
self->pc++;
}
void vm_fusub(vm* self)
{
value* lhs = vm_pop_value(self);
value* val = malloc(sizeof(value));
value_init_float(val, -lhs->val.real_float, lhs->lineno);
vm_push_value(self, val);
value_free(lhs);
free(lhs);
self->pc++;
}
void vm_fmul(vm* self)
{
value* rhs = vm_pop_value(self);
value* lhs = vm_pop_value(self);
value* val = malloc(sizeof(value));
value_init_float(val, lhs->val.real_float
* rhs->val.real_float, lhs->lineno);
vm_push_value(self, val);
value_free(rhs);
free(rhs);
value_free(lhs);
free(lhs);
self->pc++;
}
void vm_fdiv(vm* self)
{
value* rhs = vm_pop_value(self);
value* lhs = vm_pop_value(self);
value* val = malloc(sizeof(value));
value_init_float(val, lhs->val.real_float
/ rhs->val.real_float, lhs->lineno);
vm_push_value(self, val);
value_free(rhs);
free(rhs);
value_free(lhs);
free(lhs);
self->pc++;
}
void vm_fmod(vm* self)
{
value* rhs = vm_pop_value(self);
value* lhs = vm_pop_value(self);
value* val = malloc(sizeof(value));
value_init_float(val, fmod(lhs->val.real_float, rhs->val.real_float),
lhs->lineno);
vm_push_value(self, val);
value_free(rhs);
free(rhs);
value_free(lhs);
free(lhs);
self->pc++;
}
void vm_fpow(vm* self)
{
value* rhs = vm_pop_value(self);
value* lhs = vm_pop_value(self);
value* val = malloc(sizeof(value));
value_init_float(val, pow(lhs->val.real_float, rhs->val.real_float)
, lhs->lineno);
vm_push_value(self, val);
value_free(rhs);
free(rhs);
value_free(lhs);
free(lhs);
self->pc++;
}
void vm_eq(vm* self) void vm_eq(vm* self)
{ {
assert(self); assert(self);
@ -486,63 +336,3 @@ void vm_assert(vm* self)
self->pc++; self->pc++;
} }
void vm_smul(vm* self)
{
assert(self);
size_t const SZ = 1024;
char val[SZ];
value* rhs = vm_pop_value(self);
value* lhs = vm_pop_value(self);
int n = lhs->val.integer;
size_t sz = 0;
for (int i=0; i<n; i++)
{
sz += snprintf(val + sz,
SZ - sz,
"%s",
rhs->val.string);
}
value* res = malloc(sizeof(val));
value_init_string(res, val, lhs->lineno);
vm_push_value(self, res);
value_free(lhs);
free(lhs);
value_free(rhs);
free(rhs);
self->pc++;
}
void vm_cat(vm* self)
{
assert(self);
size_t const SZ = 1024;
char val[SZ];
value* rhs = vm_pop_value(self);
value* lhs = vm_pop_value(self);
snprintf(val, SZ, "%s%s", lhs->val.string, rhs->val.string);
value* res = malloc(sizeof(value));
value_init_string(res, val, lhs->lineno);
vm_push_value(self, res);
value_free(lhs);
free(lhs);
value_free(rhs);
free(rhs);
self->pc++;
}

View File

@ -38,19 +38,10 @@ void vm_idiv(vm* self);
void vm_imod(vm* self); void vm_imod(vm* self);
void vm_ipow(vm* self); void vm_ipow(vm* self);
void vm_fadd(vm* self);
void vm_fuadd(vm* self);
void vm_fsub(vm* self);
void vm_fusub(vm* self);
void vm_fmul(vm* self);
void vm_fdiv(vm* self);
void vm_fmod(vm* self);
void vm_fpow(vm* self);
void vm_eq(vm* self); void vm_eq(vm* self);
void vm_assert(vm* self); void vm_assert(vm* self);
void vm_smul(vm* self);
void vm_cat(vm* self);
#endif #endif

View File

@ -1,25 +0,0 @@
5 + 2.0
3.0 + 9
5 - 2.0
3.0 - 9
5 * 2.0
3.0 * 9
5 / 2.0
3.0 / 9
5 % 2.0
3.0 % 9
1.2 ^ 3
true + 2.0
3.0 + false
false - 2.0
3.0 - true
false * 2.0
false * 9
5 / true
true / 9
5 % false
true % 9
(false && false) ^ 3
1.2 && 2.3
1.2 || 2.3
!12.0

View File

@ -6,21 +6,25 @@
1 / true 1 / true
1 % true 1 % true
1 ^ true 1 ^ true
true + 1 true + 1
true - 1 true - 1
true * 1 true * 1
true / 1 true / 1
true % 1 true % 1
true ^ 1 true ^ 1
true + false true + false
true - false true - false
true * false true * false
true / false true / false
true % false true % false
true ^ false true ^ false
1 && true 1 && true
2 || false 2 || false
!5 !5
true && 1 true && 1
false || -2 false || -2
!!5 !!5

View File

@ -1,41 +0,0 @@
+"a"
-"a"
5 + "a"
"z" + 2
3.1 + "mpm"
"true" + true
5 - "a"
"z" - 2
3.1 - "mpm"
"true" - true
3.1 * "mpm"
"true" * true
5 / "a"
"z" / 2
3.1 / "mpm"
"true" / true
5 % "a"
"z" % 2
3.1 % "mpm"
"true" % true
5 ^ "a"
"z" ^ 2
3.1 ^ "mpm"
"true" ^ true
"aze" && true
false && "eza"
"aze" || true
false || "eza"
!"eza"
"aze" && true
false && "eza"

View File

@ -12,9 +12,9 @@ do
while read line; while read line;
do do
echo "$line" | wuz &> /dev/null echo $line | wuz &> /dev/null
RET="$?" RET="$?"
if [ "$RET" != "0" ] || [ "$line" == "" ] if [ $RET -ne 0 ] || [ "$line" == "" ]
then then
OK=$(($OK+1)) OK=$(($OK+1))
else else

View File

@ -1,13 +0,0 @@
assert 5.2 == 5.2
assert 5.2 != 5.3
:: Arithmetic
assert 7.2 == 5.1 + 2.1
assert 2.0 == + 2.0
assert 3.0 == 5.0 - 2.0
assert -5.0 == - 5.0
assert 10.0 == 5.0 * 2.0
assert 2.5 == 5.0 / 2.0
assert 1.0 == 5.0 % 2.0
assert 0.5 == 5.0 % 1.5
assert 25.0 == 5.0 ^ 2.0

View File

@ -1,8 +0,0 @@
assert "salut" == "salut"
assert "salut" != "alut"
assert "hello world" == "hello " + "world"
assert "aaaa" == 4 * "a"
assert "aaaa" == "a" * 4
assert "abababab" == ("a" + "b") * 4