add nilptrs, more conversion functions and change how ptrs work
Pointers now no longer point to the Value struct (the internal wrapper for values) but to the value itself.
This commit is contained in:
parent
befce544e7
commit
ba8d2f0702
35
main.c
35
main.c
@ -8,6 +8,7 @@
|
||||
#include "ir.h"
|
||||
#include "lex.h"
|
||||
#include "parse.h"
|
||||
#include "runtime.h"
|
||||
#include "util.h"
|
||||
#include "vm.h"
|
||||
|
||||
@ -53,10 +54,11 @@ static Value fn_int(Value *args) {
|
||||
.Int = 0,
|
||||
};
|
||||
switch (args[0].type) {
|
||||
case TypeVoid: break;
|
||||
case TypeVoid: break;
|
||||
case TypeFloat: ret.Int = (ssize_t)args[0].Float; break;
|
||||
case TypeInt: ret.Int = args[0].Int; break;
|
||||
case TypeBool: ret.Int = (ssize_t)args[0].Bool; break;
|
||||
case TypeChar: ret.Int = (ssize_t)args[0].Char; break;
|
||||
case TypeArr:
|
||||
if (args[0].Arr.is_string && args[0].Arr.type == TypeChar) {
|
||||
ssize_t endpos;
|
||||
@ -79,10 +81,11 @@ static Value fn_float(Value *args) {
|
||||
.Float = 0.0,
|
||||
};
|
||||
switch (args[0].type) {
|
||||
case TypeVoid: break;
|
||||
case TypeVoid: break;
|
||||
case TypeFloat: ret.Float = args[0].Float; break;
|
||||
case TypeInt: ret.Float = (double)args[0].Int; break;
|
||||
case TypeBool: ret.Float = (double)args[0].Bool; break;
|
||||
case TypeChar: ret.Float = (double)args[0].Char; break;
|
||||
case TypeArr:
|
||||
if (args[0].Arr.is_string && args[0].Arr.type == TypeChar) {
|
||||
ssize_t endpos;
|
||||
@ -99,6 +102,31 @@ static Value fn_float(Value *args) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Value fn_bool(Value *args) {
|
||||
return (Value){ .type = TypeBool, .Bool = is_nonzero(&args[0]) };
|
||||
}
|
||||
|
||||
static Value fn_char(Value *args) {
|
||||
Value ret = {
|
||||
.type = TypeChar,
|
||||
.Float = 0.0,
|
||||
};
|
||||
switch (args[0].type) {
|
||||
case TypeVoid: break;
|
||||
case TypeFloat: ret.Char = (char)args[0].Float; break;
|
||||
case TypeInt: ret.Char = (char)args[0].Int; break;
|
||||
case TypeBool: ret.Char = (char)args[0].Bool; break;
|
||||
case TypeChar: ret.Char = args[0].Char; break;
|
||||
default: ASSERT_UNREACHED();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Value fn_ptr(Value *args) {
|
||||
(void)args;
|
||||
return (Value){ .type = TypePtr, .Ptr = { .type = TypeVoid, .val = NULL }};
|
||||
}
|
||||
|
||||
static Value fn_pow(Value *args) {
|
||||
if (!(args[0].type == TypeFloat && args[1].type == TypeFloat)) {
|
||||
set_err("pow() requires arguments of type float");
|
||||
@ -209,6 +237,9 @@ int main(int argc, const char **argv) {
|
||||
{ .name = "putln", .kind = FuncVarArgs, .returns = false, .side_effects = true, .VarArgs = { .min_args = 0, .NoRet.func = fn_putln, }},
|
||||
{ .name = "int", .kind = FuncFixedArgs, .returns = true, .side_effects = false, .FixedArgs = { .n_args = 1, .WithRet.func = fn_int, }},
|
||||
{ .name = "float", .kind = FuncFixedArgs, .returns = true, .side_effects = false, .FixedArgs = { .n_args = 1, .WithRet.func = fn_float, }},
|
||||
{ .name = "bool", .kind = FuncFixedArgs, .returns = true, .side_effects = false, .FixedArgs = { .n_args = 1, .WithRet.func = fn_bool, }},
|
||||
{ .name = "char", .kind = FuncFixedArgs, .returns = true, .side_effects = false, .FixedArgs = { .n_args = 1, .WithRet.func = fn_char, }},
|
||||
{ .name = "ptr", .kind = FuncFixedArgs, .returns = true, .side_effects = false, .FixedArgs = { .n_args = 0, .WithRet.func = fn_ptr, }},
|
||||
{ .name = "pow", .kind = FuncFixedArgs, .returns = true, .side_effects = false, .FixedArgs = { .n_args = 2, .WithRet.func = fn_pow, }},
|
||||
{ .name = "sleep", .kind = FuncFixedArgs, .returns = false, .side_effects = true, .FixedArgs = { .n_args = 1, .NoRet.func = fn_sleep, }},
|
||||
{ .name = "getln", .kind = FuncFixedArgs, .returns = true, .side_effects = true, .FixedArgs = { .n_args = 0, .WithRet.func = fn_getln, }},
|
||||
|
@ -130,9 +130,12 @@ Value eval_unary(IRInstr instr, const Value *v) {
|
||||
|
||||
bool is_nonzero(const Value *v) {
|
||||
switch (v->type) {
|
||||
case TypeInt: return v->Int != 0;
|
||||
case TypeFloat: return v->Float != 0.0;
|
||||
case TypeInt: return v->Int != 0;
|
||||
case TypeFloat: return v->Float != 0.0;
|
||||
case TypeBool: return v->Bool;
|
||||
case TypeChar: return v->Char != 0;
|
||||
case TypePtr: return v->Ptr.val != NULL;
|
||||
case TypeArr: return v->Arr.len != 0;
|
||||
default: ASSERT_UNREACHED();
|
||||
}
|
||||
}
|
||||
|
15
tok.c
15
tok.c
@ -11,6 +11,7 @@ size_t type_size[TypeEnumSize] = {
|
||||
[TypeInt] = sizeof(((Value*)NULL)->Int),
|
||||
[TypeBool] = sizeof(((Value*)NULL)->Bool),
|
||||
[TypeChar] = sizeof(((Value*)NULL)->Char),
|
||||
[TypePtr] = sizeof(((Value*)NULL)->Ptr),
|
||||
[TypeArr] = sizeof(((Value*)NULL)->Arr),
|
||||
};
|
||||
|
||||
@ -47,11 +48,17 @@ void print_value(const Value *v, bool raw) {
|
||||
else printf("'%c'", v->Char);
|
||||
}
|
||||
break;
|
||||
case TypePtr:
|
||||
printf("ptr<%s>(", type_str[v->Ptr.type]);
|
||||
print_value(v->Ptr.val, false);
|
||||
printf(")");
|
||||
case TypePtr: {
|
||||
if (v->Ptr.val) {
|
||||
printf("ptr<%s>(", type_str[v->Ptr.type]);
|
||||
Value deref = { .type = v->Ptr.type };
|
||||
memcpy(&deref.Void, v->Ptr.val, type_size[v->Ptr.type]);
|
||||
print_value(&deref, false);
|
||||
printf(")");
|
||||
} else
|
||||
printf("ptr<%s>(nil)", type_str[v->Ptr.type]);
|
||||
break;
|
||||
}
|
||||
case TypeArr:
|
||||
if (v->Arr.is_string) {
|
||||
if (v->Arr.type != TypeChar)
|
||||
|
2
tok.h
2
tok.h
@ -31,7 +31,7 @@ typedef struct Value {
|
||||
char Char;
|
||||
struct {
|
||||
Type type;
|
||||
struct Value *val;
|
||||
void *val;
|
||||
} Ptr;
|
||||
struct {
|
||||
Type type;
|
||||
|
Loading…
Reference in New Issue
Block a user