Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
801b28e27d | ||
|
|
c0df5fc9d4 | ||
|
|
f0e641928d |
+16
-7
@@ -7,12 +7,11 @@ fn doSome(A a) A
|
||||
{
|
||||
// NOTE: section below won't change `a.some` value
|
||||
|
||||
// if (a.some < 1)
|
||||
// {
|
||||
// a.some = 1;
|
||||
// return a;
|
||||
// }
|
||||
if (a.some < 1)
|
||||
{
|
||||
a.some = 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
@@ -27,10 +26,20 @@ fn doSomeNew() A
|
||||
|
||||
A a = new A;
|
||||
a.some = 0;
|
||||
printline(a);
|
||||
if (a.some != 0)
|
||||
{
|
||||
printline("Test failed (first a.some != 0)");
|
||||
exit(1);
|
||||
}
|
||||
else printline(a);
|
||||
|
||||
a = doSome(a);
|
||||
printline(a);
|
||||
if (a.some != 1)
|
||||
{
|
||||
printline("Test failed (2nd a.some != 1)");
|
||||
exit(1);
|
||||
}
|
||||
else printline(a);
|
||||
|
||||
A b = doSomeNew();
|
||||
printline(b);
|
||||
|
||||
+5
-1
@@ -28,5 +28,9 @@ printline(obj.y);
|
||||
|
||||
if (obj.x == 10 && obj.y == 10)
|
||||
printline("Test passed");
|
||||
else printline("Test failed");
|
||||
else
|
||||
{
|
||||
printline("Test failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
bool flag = true;
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
printline("buhhh, flag is not true");
|
||||
exit(1);
|
||||
}
|
||||
else if (2 + 2 >= 4)
|
||||
{
|
||||
printline ("two plus two is four");
|
||||
}
|
||||
else {
|
||||
printline("gotcha");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
+10
-2
@@ -15,10 +15,18 @@ printline("Test #1: fibonacci");
|
||||
int result = fib(7);
|
||||
if (result == 13)
|
||||
printline("Recurse test passed");
|
||||
else printline("Recurse test failed");
|
||||
else
|
||||
{
|
||||
printline("Recurse test failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printline("Test #2: sum");
|
||||
if (sum(2, 2) == 4)
|
||||
printline("Sum test passed");
|
||||
else printline("Sum test failed");
|
||||
else
|
||||
{
|
||||
printline("Sum test failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -58,5 +58,9 @@ printline(total);
|
||||
|
||||
if (total == 16)
|
||||
printline("Tests passed!");
|
||||
else printline("Tests failed");
|
||||
else
|
||||
{
|
||||
printline("Tests failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
+14
-2
@@ -21,14 +21,26 @@ a.name = "Buryatka";
|
||||
a.age = 5;
|
||||
|
||||
Animal b = a.copy();
|
||||
a.name = "Gavryusha";
|
||||
a.age = 10;
|
||||
b.name = "Gavryusha";
|
||||
b.age = 10;
|
||||
|
||||
printline(a);
|
||||
printline(b);
|
||||
|
||||
printline("Types are same:");
|
||||
printline(a.type == b.type);
|
||||
|
||||
printline("Names are NOT the same");
|
||||
printline(a.name != b.name);
|
||||
|
||||
printline("1st age less than 2nd");
|
||||
printline(a.age < b.age);
|
||||
|
||||
if (a.type == b.type && a.name != b.name && a.age < b.age)
|
||||
printline("Test passed");
|
||||
else
|
||||
{
|
||||
printline("Test failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FZL_BUILTIN_PRINTLINE // Print message in arg with newline at end
|
||||
FZL_BUILTIN_PRINTLINE, // Print message in arg with newline at end
|
||||
FZL_BUILTIN_EXIT, // Exit program with code specified in arg
|
||||
} fzl_builtin_t;
|
||||
|
||||
#endif // FZL_BUILTINS_H
|
||||
|
||||
@@ -25,6 +25,7 @@ typedef enum
|
||||
FZL_OPCODE_GET_FIELD = 0xFA0002, // Get field N of an object at dstack
|
||||
FZL_OPCODE_SET_FIELD = 0xFA0003, // Set field N of an object at dstack
|
||||
FZL_OPCODE_ESCAPE_OBJECT = 0xFA0004, // Make parent envtable as owner
|
||||
FZL_OPCODE_DEREFERENCE = 0xFA0005, // Dereference address
|
||||
|
||||
FZL_OPCODE_ADD = 0xA00001, // Sum two numbers in dstack
|
||||
FZL_OPCODE_SUB = 0xA00002, // Subract two numbers in dstack
|
||||
|
||||
@@ -754,6 +754,30 @@ fzl_walk_res_t walk(fzl_walker_t *walker, fzl_node_t *node)
|
||||
}
|
||||
current_res = (fzl_walk_res_t){.type = FZL_TYPE_NULL, .error = false};
|
||||
}
|
||||
else if (strcmp(node->token->value, "exit") == 0)
|
||||
{
|
||||
if (node->call.args_count > 0)
|
||||
{
|
||||
for (size_t i = 0; i < node->call.args_count; i++)
|
||||
{
|
||||
fzl_walk_res_t res = walk(walker, node->call.args[i]);
|
||||
if (res.error)
|
||||
return res;
|
||||
}
|
||||
|
||||
push_op(walker, FZL_OPCODE_CALL_BUILTIN);
|
||||
push_word(walker, FZL_BUILTIN_EXIT);
|
||||
if (node->call.args_count < 1)
|
||||
{
|
||||
snprintf(wlast_err, sizeof(wlast_err),
|
||||
"'%s': 'exit' call with zero arguments at %ld:%ld",
|
||||
node->token->filename, node->token->ln, node->token->cn);
|
||||
return (fzl_walk_res_t){.error = true, .error_msg = wlast_err};
|
||||
}
|
||||
current_res =
|
||||
(fzl_walk_res_t){.type = FZL_TYPE_NULL, .error = false};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (node->call.callee->type == FZL_NODETYPE_IDENTIFIER)
|
||||
@@ -778,8 +802,9 @@ fzl_walk_res_t walk(fzl_walker_t *walker, fzl_node_t *node)
|
||||
if (!found)
|
||||
{
|
||||
snprintf(wlast_err, sizeof(wlast_err),
|
||||
"call to unknown function '%s'",
|
||||
(char *)node->token->value);
|
||||
"'%s': call to unknown function '%s' at %ld:%ld",
|
||||
node->token->filename, (char *)node->token->value,
|
||||
node->token->ln, node->token->cn);
|
||||
return (fzl_walk_res_t){.error = true, .error_msg = wlast_err};
|
||||
}
|
||||
|
||||
@@ -917,6 +942,7 @@ fzl_walk_res_t walk(fzl_walker_t *walker, fzl_node_t *node)
|
||||
fzl_token_t *tok = node->token;
|
||||
push_op(walker, FZL_OPCODE_PUSHNUM);
|
||||
push_word(walker, 0);
|
||||
push_op(walker, FZL_OPCODE_DEREFERENCE);
|
||||
current_res = (fzl_walk_res_t){
|
||||
.type = FZL_TYPE_OBJECT, .error = false, .classname = null_name};
|
||||
}
|
||||
|
||||
+53
-4
@@ -279,6 +279,37 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case FZL_OPCODE_DEREFERENCE:
|
||||
{
|
||||
if (vm->dtop < 1)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err),
|
||||
"runtime error - expected value in data stack");
|
||||
print_err_data(vm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fzl_value_t addr = vm->dstack[--vm->dtop];
|
||||
if (addr.type < FZL_TYPE_INT8)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err),
|
||||
"runtime error - expected address");
|
||||
print_err_data(vm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (addr.as.u == 0)
|
||||
{
|
||||
vm->dstack[vm->dtop++] =
|
||||
(fzl_value_t){.type = FZL_TYPE_OBJECT, .as.obj = NULL};
|
||||
break;
|
||||
}
|
||||
|
||||
vm->dstack[vm->dtop++] = (fzl_value_t){
|
||||
.type = FZL_TYPE_OBJECT, .as.obj = (fzl_vm_object_t *)addr.as.u};
|
||||
break;
|
||||
}
|
||||
|
||||
case FZL_OPCODE_CMP_EQ_STR:
|
||||
{
|
||||
if (vm->dtop < 2)
|
||||
@@ -359,7 +390,7 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
return -1;
|
||||
}
|
||||
fzl_value_t obj = vm->dstack[--vm->dtop];
|
||||
if (obj.type != FZL_TYPE_OBJECT && obj.type < FZL_TYPE_INT8)
|
||||
if (obj.type != FZL_TYPE_OBJECT)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err),
|
||||
"runtime error - cannot escape non-object type");
|
||||
@@ -538,8 +569,8 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
return -1;
|
||||
}
|
||||
|
||||
fzl_value_t llt = vm->dstack[--vm->dtop];
|
||||
fzl_value_t rlt = vm->dstack[--vm->dtop];
|
||||
fzl_value_t llt = vm->dstack[--vm->dtop];
|
||||
vm->dstack[vm->dtop++] =
|
||||
(fzl_value_t){.type = FZL_TYPE_BOOL, .as.b = llt.as.u < rlt.as.u};
|
||||
break;
|
||||
@@ -679,8 +710,21 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
fzl_value_t writevar = vm->dstack[--vm->dtop];
|
||||
fzl_value_t value = vm->dstack[--vm->dtop];
|
||||
|
||||
fzl_vm_env_wresult_t wresult = fzl_env_writevalue(
|
||||
vm->estack[vm->etop - 1], (char *)writevar.as.s.value, value);
|
||||
char *wrname = (char *)writevar.as.s.value;
|
||||
bool wrfound;
|
||||
fzl_value_t wrenv;
|
||||
ssize_t wrlvl = -1;
|
||||
for (ssize_t i = vm->etop - 1; i >= 0; i--)
|
||||
{
|
||||
if ((wrfound = fzl_env_lookup(vm->estack[i], wrname, &wrenv)))
|
||||
{
|
||||
wrlvl = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fzl_vm_env_wresult_t wresult =
|
||||
fzl_env_writevalue(vm->estack[wrlvl], (char *)wrname, value);
|
||||
if (wresult != FZL_VM_ENV_WRESULT_OK)
|
||||
{
|
||||
switch (wresult)
|
||||
@@ -769,6 +813,11 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
else if (arg.type == FZL_TYPE_OBJECT)
|
||||
print_object(arg.as.obj);
|
||||
}
|
||||
else if (fn_id == FZL_BUILTIN_EXIT)
|
||||
{
|
||||
fzl_value_t arg = vm->dstack[--vm->dtop];
|
||||
exit(arg.as.i);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err),
|
||||
|
||||
@@ -20,6 +20,10 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
|
||||
|
||||
switch (vm->ops[i])
|
||||
{
|
||||
case FZL_OPCODE_DEREFERENCE:
|
||||
printf("DEREFERENCE\n");
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_CMP_EQ_STR:
|
||||
printf("CMP_EQ_STR\n");
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user