Compare commits
3
Commits
dce64e8b4d
...
801b28e27d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
801b28e27d | ||
|
|
c0df5fc9d4 | ||
|
|
f0e641928d |
+17
-8
@@ -7,12 +7,11 @@ fn doSome(A a) A
|
|||||||
{
|
{
|
||||||
// NOTE: section below won't change `a.some` value
|
// NOTE: section below won't change `a.some` value
|
||||||
|
|
||||||
// if (a.some < 1)
|
if (a.some < 1)
|
||||||
// {
|
{
|
||||||
// a.some = 1;
|
a.some = 1;
|
||||||
// return a;
|
return a;
|
||||||
// }
|
}
|
||||||
a.some = 1;
|
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
@@ -27,10 +26,20 @@ fn doSomeNew() A
|
|||||||
|
|
||||||
A a = new A;
|
A a = new A;
|
||||||
a.some = 0;
|
a.some = 0;
|
||||||
printline(a);
|
if (a.some != 0)
|
||||||
|
{
|
||||||
|
printline("Test failed (first a.some != 0)");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
else printline(a);
|
||||||
|
|
||||||
a = doSome(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();
|
A b = doSomeNew();
|
||||||
printline(b);
|
printline(b);
|
||||||
|
|||||||
+5
-1
@@ -28,5 +28,9 @@ printline(obj.y);
|
|||||||
|
|
||||||
if (obj.x == 10 && obj.y == 10)
|
if (obj.x == 10 && obj.y == 10)
|
||||||
printline("Test passed");
|
printline("Test passed");
|
||||||
else printline("Test failed");
|
else
|
||||||
|
{
|
||||||
|
printline("Test failed");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
bool flag = true;
|
bool flag = true;
|
||||||
|
|
||||||
if (!flag)
|
if (!flag)
|
||||||
|
{
|
||||||
printline("buhhh, flag is not true");
|
printline("buhhh, flag is not true");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
else if (2 + 2 >= 4)
|
else if (2 + 2 >= 4)
|
||||||
{
|
{
|
||||||
printline ("two plus two is four");
|
printline ("two plus two is four");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printline("gotcha");
|
printline("gotcha");
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
+10
-2
@@ -15,10 +15,18 @@ printline("Test #1: fibonacci");
|
|||||||
int result = fib(7);
|
int result = fib(7);
|
||||||
if (result == 13)
|
if (result == 13)
|
||||||
printline("Recurse test passed");
|
printline("Recurse test passed");
|
||||||
else printline("Recurse test failed");
|
else
|
||||||
|
{
|
||||||
|
printline("Recurse test failed");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
printline("Test #2: sum");
|
printline("Test #2: sum");
|
||||||
if (sum(2, 2) == 4)
|
if (sum(2, 2) == 4)
|
||||||
printline("Sum test passed");
|
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)
|
if (total == 16)
|
||||||
printline("Tests passed!");
|
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;
|
a.age = 5;
|
||||||
|
|
||||||
Animal b = a.copy();
|
Animal b = a.copy();
|
||||||
a.name = "Gavryusha";
|
b.name = "Gavryusha";
|
||||||
a.age = 10;
|
b.age = 10;
|
||||||
|
|
||||||
printline(a);
|
printline(a);
|
||||||
printline(b);
|
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)
|
if (a.type == b.type && a.name != b.name && a.age < b.age)
|
||||||
printline("Test passed");
|
printline("Test passed");
|
||||||
else
|
else
|
||||||
|
{
|
||||||
printline("Test failed");
|
printline("Test failed");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
typedef enum
|
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;
|
} fzl_builtin_t;
|
||||||
|
|
||||||
#endif // FZL_BUILTINS_H
|
#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_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_SET_FIELD = 0xFA0003, // Set field N of an object at dstack
|
||||||
FZL_OPCODE_ESCAPE_OBJECT = 0xFA0004, // Make parent envtable as owner
|
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_ADD = 0xA00001, // Sum two numbers in dstack
|
||||||
FZL_OPCODE_SUB = 0xA00002, // Subract 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};
|
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
|
else
|
||||||
{
|
{
|
||||||
if (node->call.callee->type == FZL_NODETYPE_IDENTIFIER)
|
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)
|
if (!found)
|
||||||
{
|
{
|
||||||
snprintf(wlast_err, sizeof(wlast_err),
|
snprintf(wlast_err, sizeof(wlast_err),
|
||||||
"call to unknown function '%s'",
|
"'%s': call to unknown function '%s' at %ld:%ld",
|
||||||
(char *)node->token->value);
|
node->token->filename, (char *)node->token->value,
|
||||||
|
node->token->ln, node->token->cn);
|
||||||
return (fzl_walk_res_t){.error = true, .error_msg = wlast_err};
|
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;
|
fzl_token_t *tok = node->token;
|
||||||
push_op(walker, FZL_OPCODE_PUSHNUM);
|
push_op(walker, FZL_OPCODE_PUSHNUM);
|
||||||
push_word(walker, 0);
|
push_word(walker, 0);
|
||||||
|
push_op(walker, FZL_OPCODE_DEREFERENCE);
|
||||||
current_res = (fzl_walk_res_t){
|
current_res = (fzl_walk_res_t){
|
||||||
.type = FZL_TYPE_OBJECT, .error = false, .classname = null_name};
|
.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)
|
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:
|
case FZL_OPCODE_CMP_EQ_STR:
|
||||||
{
|
{
|
||||||
if (vm->dtop < 2)
|
if (vm->dtop < 2)
|
||||||
@@ -359,7 +390,7 @@ int fzl_vm_run(fzl_vm_t *vm)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fzl_value_t obj = vm->dstack[--vm->dtop];
|
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),
|
snprintf(last_err, sizeof(last_err),
|
||||||
"runtime error - cannot escape non-object type");
|
"runtime error - cannot escape non-object type");
|
||||||
@@ -538,8 +569,8 @@ int fzl_vm_run(fzl_vm_t *vm)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fzl_value_t llt = vm->dstack[--vm->dtop];
|
|
||||||
fzl_value_t rlt = vm->dstack[--vm->dtop];
|
fzl_value_t rlt = vm->dstack[--vm->dtop];
|
||||||
|
fzl_value_t llt = vm->dstack[--vm->dtop];
|
||||||
vm->dstack[vm->dtop++] =
|
vm->dstack[vm->dtop++] =
|
||||||
(fzl_value_t){.type = FZL_TYPE_BOOL, .as.b = llt.as.u < rlt.as.u};
|
(fzl_value_t){.type = FZL_TYPE_BOOL, .as.b = llt.as.u < rlt.as.u};
|
||||||
break;
|
break;
|
||||||
@@ -679,8 +710,21 @@ int fzl_vm_run(fzl_vm_t *vm)
|
|||||||
fzl_value_t writevar = vm->dstack[--vm->dtop];
|
fzl_value_t writevar = vm->dstack[--vm->dtop];
|
||||||
fzl_value_t value = vm->dstack[--vm->dtop];
|
fzl_value_t value = vm->dstack[--vm->dtop];
|
||||||
|
|
||||||
fzl_vm_env_wresult_t wresult = fzl_env_writevalue(
|
char *wrname = (char *)writevar.as.s.value;
|
||||||
vm->estack[vm->etop - 1], (char *)writevar.as.s.value, 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)
|
if (wresult != FZL_VM_ENV_WRESULT_OK)
|
||||||
{
|
{
|
||||||
switch (wresult)
|
switch (wresult)
|
||||||
@@ -769,6 +813,11 @@ int fzl_vm_run(fzl_vm_t *vm)
|
|||||||
else if (arg.type == FZL_TYPE_OBJECT)
|
else if (arg.type == FZL_TYPE_OBJECT)
|
||||||
print_object(arg.as.obj);
|
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
|
else
|
||||||
{
|
{
|
||||||
snprintf(last_err, sizeof(last_err),
|
snprintf(last_err, sizeof(last_err),
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
|
|||||||
|
|
||||||
switch (vm->ops[i])
|
switch (vm->ops[i])
|
||||||
{
|
{
|
||||||
|
case FZL_OPCODE_DEREFERENCE:
|
||||||
|
printf("DEREFERENCE\n");
|
||||||
|
break;
|
||||||
|
|
||||||
case FZL_OPCODE_CMP_EQ_STR:
|
case FZL_OPCODE_CMP_EQ_STR:
|
||||||
printf("CMP_EQ_STR\n");
|
printf("CMP_EQ_STR\n");
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user