move type enum out of struct

This commit is contained in:
r4 2021-12-28 13:55:01 +01:00
parent 0d5313a063
commit befce544e7
6 changed files with 61 additions and 69 deletions

22
lex.c
View File

@ -81,9 +81,9 @@ TokList lex(const char *s, Pool *static_vars) {
else if (streq_0_n("while", start, i)) else if (streq_0_n("while", start, i))
emit(&toks, &pos, (Tok){ .kind = TokWhile }); emit(&toks, &pos, (Tok){ .kind = TokWhile });
else if (streq_0_n("true", start, i)) else if (streq_0_n("true", start, i))
emit(&toks, &pos, (Tok){ .kind = TokVal, .Val = { .type = { .kind = TypeBool, }, .Bool = true, }, }); emit(&toks, &pos, (Tok){ .kind = TokVal, .Val = { .type = TypeBool, .Bool = true }});
else if (streq_0_n("false", start, i)) else if (streq_0_n("false", start, i))
emit(&toks, &pos, (Tok){ .kind = TokVal, .Val = { .type = { .kind = TypeBool, }, .Bool = false, }, }); emit(&toks, &pos, (Tok){ .kind = TokVal, .Val = { .type = TypeBool, .Bool = false }});
else { else {
emit(&toks, &pos, (Tok){ emit(&toks, &pos, (Tok){
.kind = TokIdent, .kind = TokIdent,
@ -146,9 +146,7 @@ TokList lex(const char *s, Pool *static_vars) {
emit(&toks, &pos, (Tok){ emit(&toks, &pos, (Tok){
.kind = TokVal, .kind = TokVal,
.Val = { .Val = {
.type = { .type = TypeFloat,
.kind = TypeFloat,
},
.Float = num, .Float = num,
}, },
}); });
@ -164,9 +162,7 @@ TokList lex(const char *s, Pool *static_vars) {
emit(&toks, &pos, (Tok){ emit(&toks, &pos, (Tok){
.kind = TokVal, .kind = TokVal,
.Val = { .Val = {
.type = { .type = TypeInt,
.kind = TypeInt,
},
.Int = num, .Int = num,
}, },
}); });
@ -234,9 +230,9 @@ TokList lex(const char *s, Pool *static_vars) {
case '!': case '!':
consume(&pos, *(s++)); consume(&pos, *(s++));
if (s[0] == '=') if (s[0] == '=')
emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpNeq, }); emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpNeq });
else { else {
emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpNot, }); emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpNot });
continue; continue;
} }
break; break;
@ -310,7 +306,7 @@ TokList lex(const char *s, Pool *static_vars) {
set_err("Unclosed char literal"); set_err("Unclosed char literal");
return toks; return toks;
} }
emit(&toks, &pos, (Tok){ .kind = TokVal, .Val = { .type = { .kind = TypeChar, }, .Char = c, }, }); emit(&toks, &pos, (Tok){ .kind = TokVal, .Val = { .type = TypeChar, .Char = c }});
break; break;
} }
case '"': { case '"': {
@ -348,10 +344,10 @@ TokList lex(const char *s, Pool *static_vars) {
str[i] = c; str[i] = c;
} }
emit(&toks, &pos, (Tok){ .kind = TokVal, .Val = { emit(&toks, &pos, (Tok){ .kind = TokVal, .Val = {
.type.kind = TypeArr, .type = TypeArr,
.Arr = { .Arr = {
.is_string = true, .is_string = true,
.type.kind = TypeChar, .type = TypeChar,
.vals = str, .vals = str,
.len = size, .len = size,
.cap = size, .cap = size,

22
main.c
View File

@ -49,16 +49,16 @@ static void fn_putln(size_t extra_args, Value *args) {
static Value fn_int(Value *args) { static Value fn_int(Value *args) {
Value ret = { Value ret = {
.type.kind = TypeInt, .type = TypeInt,
.Int = 0, .Int = 0,
}; };
switch (args[0].type.kind) { switch (args[0].type) {
case TypeVoid: break; case TypeVoid: break;
case TypeFloat: ret.Int = (ssize_t)args[0].Float; break; case TypeFloat: ret.Int = (ssize_t)args[0].Float; break;
case TypeInt: ret.Int = args[0].Int; break; case TypeInt: ret.Int = args[0].Int; break;
case TypeBool: ret.Int = (ssize_t)args[0].Bool; break; case TypeBool: ret.Int = (ssize_t)args[0].Bool; break;
case TypeArr: case TypeArr:
if (args[0].Arr.is_string && args[0].Arr.type.kind == TypeChar) { if (args[0].Arr.is_string && args[0].Arr.type == TypeChar) {
ssize_t endpos; ssize_t endpos;
ret.Int = stoimax((char*)args[0].Arr.vals, args[0].Arr.len, 10, &endpos); ret.Int = stoimax((char*)args[0].Arr.vals, args[0].Arr.len, 10, &endpos);
if (endpos != -1) { if (endpos != -1) {
@ -75,16 +75,16 @@ static Value fn_int(Value *args) {
static Value fn_float(Value *args) { static Value fn_float(Value *args) {
Value ret = { Value ret = {
.type.kind = TypeFloat, .type = TypeFloat,
.Float = 0.0, .Float = 0.0,
}; };
switch (args[0].type.kind) { switch (args[0].type) {
case TypeVoid: break; case TypeVoid: break;
case TypeFloat: ret.Float = args[0].Float; break; case TypeFloat: ret.Float = args[0].Float; break;
case TypeInt: ret.Float = (double)args[0].Int; break; case TypeInt: ret.Float = (double)args[0].Int; break;
case TypeBool: ret.Float = (double)args[0].Bool; break; case TypeBool: ret.Float = (double)args[0].Bool; break;
case TypeArr: case TypeArr:
if (args[0].Arr.is_string && args[0].Arr.type.kind == TypeChar) { if (args[0].Arr.is_string && args[0].Arr.type == TypeChar) {
ssize_t endpos; ssize_t endpos;
ret.Float = stod((char*)args[0].Arr.vals, args[0].Arr.len, &endpos); ret.Float = stod((char*)args[0].Arr.vals, args[0].Arr.len, &endpos);
if (endpos != -1) { if (endpos != -1) {
@ -100,18 +100,18 @@ static Value fn_float(Value *args) {
} }
static Value fn_pow(Value *args) { static Value fn_pow(Value *args) {
if (!(args[0].type.kind == TypeFloat && args[1].type.kind == TypeFloat)) { if (!(args[0].type == TypeFloat && args[1].type == TypeFloat)) {
set_err("pow() requires arguments of type float"); set_err("pow() requires arguments of type float");
return (Value){0}; return (Value){0};
} }
return (Value){ return (Value){
.type.kind = TypeFloat, .type = TypeFloat,
.Float = pow(args[0].Float, args[1].Float), .Float = pow(args[0].Float, args[1].Float),
}; };
} }
static void fn_sleep(Value *args) { static void fn_sleep(Value *args) {
if (!(args[0].type.kind == TypeFloat && args[0].Float >= 0.0)) { if (!(args[0].type == TypeFloat && args[0].Float >= 0.0)) {
set_err("sleep() requires a positive float"); set_err("sleep() requires a positive float");
return; return;
} }
@ -135,10 +135,10 @@ static Value fn_getln(Value *args) {
} }
return (Value){ return (Value){
.type.kind = TypeArr, .type = TypeArr,
.Arr = { .Arr = {
.is_string = true, .is_string = true,
.type.kind = TypeChar, .type = TypeChar,
.vals = line, .vals = line,
.len = len, .len = len,
.cap = cap, .cap = cap,

View File

@ -8,7 +8,7 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
case IRSub: case IRSub:
case IRMul: case IRMul:
case IRDiv: { case IRDiv: {
if (lhs->type.kind == TypeInt && rhs->type.kind == TypeInt) { if (lhs->type == TypeInt && rhs->type == TypeInt) {
ssize_t res; ssize_t res;
switch (instr) { switch (instr) {
case IRAdd: res = lhs->Int + rhs->Int; break; case IRAdd: res = lhs->Int + rhs->Int; break;
@ -18,10 +18,10 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
default: ASSERT_UNREACHED(); default: ASSERT_UNREACHED();
} }
return (Value){ return (Value){
.type.kind = TypeInt, .type = TypeInt,
.Int = res, .Int = res,
}; };
} else if (lhs->type.kind == TypeFloat && rhs->type.kind == TypeFloat) { } else if (lhs->type == TypeFloat && rhs->type == TypeFloat) {
double res; double res;
switch (instr) { switch (instr) {
case IRAdd: res = lhs->Float + rhs->Float; break; case IRAdd: res = lhs->Float + rhs->Float; break;
@ -31,11 +31,11 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
default: ASSERT_UNREACHED(); default: ASSERT_UNREACHED();
} }
return (Value){ return (Value){
.type.kind = TypeFloat, .type = TypeFloat,
.Float = res, .Float = res,
}; };
} else { } else {
set_err("Unsupported types for operation '%s': %s and %s", irinstr_str[instr], type_str[lhs->type.kind], type_str[rhs->type.kind]); set_err("Unsupported types for operation '%s': %s and %s", irinstr_str[instr], type_str[lhs->type], type_str[rhs->type]);
return (Value){0}; return (Value){0};
} }
} }
@ -44,7 +44,7 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
case IRLt: case IRLt:
case IRLe: { case IRLe: {
bool res; bool res;
if (lhs->type.kind == TypeInt && rhs->type.kind == TypeInt) { if (lhs->type == TypeInt && rhs->type == TypeInt) {
switch (instr) { switch (instr) {
case IREq: res = lhs->Int == rhs->Int; break; case IREq: res = lhs->Int == rhs->Int; break;
case IRNeq: res = lhs->Int != rhs->Int; break; case IRNeq: res = lhs->Int != rhs->Int; break;
@ -52,7 +52,7 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
case IRLe: res = lhs->Int <= rhs->Int; break; case IRLe: res = lhs->Int <= rhs->Int; break;
default: ASSERT_UNREACHED(); default: ASSERT_UNREACHED();
}; };
} else if (lhs->type.kind == TypeFloat && rhs->type.kind == TypeFloat) { } else if (lhs->type == TypeFloat && rhs->type == TypeFloat) {
switch (instr) { switch (instr) {
case IREq: res = lhs->Float == rhs->Float; break; case IREq: res = lhs->Float == rhs->Float; break;
case IRNeq: res = lhs->Float != rhs->Float; break; case IRNeq: res = lhs->Float != rhs->Float; break;
@ -60,8 +60,8 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
case IRLe: res = lhs->Float <= rhs->Float; break; case IRLe: res = lhs->Float <= rhs->Float; break;
default: ASSERT_UNREACHED(); default: ASSERT_UNREACHED();
}; };
} else if (lhs->type.kind == TypeArr && lhs->Arr.type.kind == TypeChar && lhs->Arr.is_string && } else if (lhs->type == TypeArr && lhs->Arr.type == TypeChar && lhs->Arr.is_string &&
rhs->type.kind == TypeArr && rhs->Arr.type.kind == TypeChar && rhs->Arr.is_string) { rhs->type == TypeArr && rhs->Arr.type == TypeChar && rhs->Arr.is_string) {
switch (instr) { switch (instr) {
case IREq: case IREq:
res = lhs->Arr.len == rhs->Arr.len ? strncmp(lhs->Arr.vals, rhs->Arr.vals, lhs->Arr.len) == 0 : false; res = lhs->Arr.len == rhs->Arr.len ? strncmp(lhs->Arr.vals, rhs->Arr.vals, lhs->Arr.len) == 0 : false;
@ -74,23 +74,23 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
break; break;
}; };
} else { } else {
set_err("Unsupported types for operation '%s': %s and %s", irinstr_str[instr], type_str[lhs->type.kind], type_str[rhs->type.kind]); set_err("Unsupported types for operation '%s': %s and %s", irinstr_str[instr], type_str[lhs->type], type_str[rhs->type]);
return (Value){0}; return (Value){0};
} }
return (Value){ return (Value){
.type.kind = TypeBool, .type = TypeBool,
.Bool = res, .Bool = res,
}; };
} }
case IRAnd: case IRAnd:
return (Value){ return (Value){
.type.kind = TypeBool, .type = TypeBool,
.Bool = is_nonzero(lhs) && is_nonzero(rhs), .Bool = is_nonzero(lhs) && is_nonzero(rhs),
}; };
break; break;
case IROr: case IROr:
return (Value){ return (Value){
.type.kind = TypeBool, .type = TypeBool,
.Bool = is_nonzero(lhs) || is_nonzero(rhs), .Bool = is_nonzero(lhs) || is_nonzero(rhs),
}; };
break; break;
@ -105,19 +105,19 @@ Value eval_unary(IRInstr instr, const Value *v) {
case IRSet: case IRSet:
return *v; return *v;
case IRNeg: case IRNeg:
if (v->type.kind == TypeInt) if (v->type == TypeInt)
return (Value){ .type.kind = TypeInt, .Int = -v->Int }; return (Value){ .type = TypeInt, .Int = -v->Int };
else if (v->type.kind == TypeFloat) else if (v->type == TypeFloat)
return (Value){ .type.kind = TypeFloat, .Float = -v->Float }; return (Value){ .type = TypeFloat, .Float = -v->Float };
else { else {
set_err("Unsupported type for operation '%s': %s", irinstr_str[instr], type_str[v->type.kind]); set_err("Unsupported type for operation '%s': %s", irinstr_str[instr], type_str[v->type]);
return (Value){0}; return (Value){0};
} }
case IRNot: case IRNot:
if (v->type.kind == TypeBool) { if (v->type == TypeBool) {
return (Value){ .type.kind = TypeBool, .Bool = !v->Bool }; return (Value){ .type = TypeBool, .Bool = !v->Bool };
} else { } else {
set_err("Unsupported type for operation '%s': %s", irinstr_str[instr], type_str[v->type.kind]); set_err("Unsupported type for operation '%s': %s", irinstr_str[instr], type_str[v->type]);
return (Value){0}; return (Value){0};
} }
case IRAddrOf: case IRAddrOf:
@ -129,7 +129,7 @@ Value eval_unary(IRInstr instr, const Value *v) {
} }
bool is_nonzero(const Value *v) { bool is_nonzero(const Value *v) {
switch (v->type.kind) { switch (v->type) {
case TypeInt: return v->Int != 0; case TypeInt: return v->Int != 0;
case TypeFloat: return v->Float != 0.0; case TypeFloat: return v->Float != 0.0;
case TypeBool: return v->Bool; case TypeBool: return v->Bool;
@ -140,7 +140,7 @@ bool is_nonzero(const Value *v) {
Value zero_val(Type ty) { Value zero_val(Type ty) {
Value ret; Value ret;
ret.type = ty; ret.type = ty;
switch (ty.kind) { switch (ty) {
case TypeInt: ret.Int = 0; break; case TypeInt: ret.Int = 0; break;
case TypeFloat: ret.Float = 0.0; break; case TypeFloat: ret.Float = 0.0; break;
case TypeBool: ret.Bool = false; break; case TypeBool: ret.Bool = false; break;

8
tok.c
View File

@ -25,7 +25,7 @@ const char *type_str[TypeEnumSize] = {
}; };
void print_value(const Value *v, bool raw) { void print_value(const Value *v, bool raw) {
switch (v->type.kind) { switch (v->type) {
case TypeVoid: case TypeVoid:
printf("(void)"); printf("(void)");
break; break;
@ -48,13 +48,13 @@ void print_value(const Value *v, bool raw) {
} }
break; break;
case TypePtr: case TypePtr:
printf("ptr<%s>(", type_str[v->Ptr.type.kind]); printf("ptr<%s>(", type_str[v->Ptr.type]);
print_value(v->Ptr.val, false); print_value(v->Ptr.val, false);
printf(")"); printf(")");
break; break;
case TypeArr: case TypeArr:
if (v->Arr.is_string) { if (v->Arr.is_string) {
if (v->Arr.type.kind != TypeChar) if (v->Arr.type != TypeChar)
ASSERT_UNREACHED(); ASSERT_UNREACHED();
char *str = v->Arr.vals; char *str = v->Arr.vals;
if (!raw) if (!raw)
@ -74,7 +74,7 @@ void print_value(const Value *v, bool raw) {
} else { } else {
printf("["); printf("[");
for (size_t i = 0;; i++) { for (size_t i = 0;; i++) {
size_t ty_sz = type_size[v->Arr.type.kind]; size_t ty_sz = type_size[v->Arr.type];
Value ty_val = { .type = v->Arr.type }; Value ty_val = { .type = v->Arr.type };
memcpy(&ty_val.Void, (uint8_t*)v->Arr.vals + ty_sz * i, ty_sz); memcpy(&ty_val.Void, (uint8_t*)v->Arr.vals + ty_sz * i, ty_sz);
print_value(&ty_val, false); print_value(&ty_val, false);

28
tok.h
View File

@ -5,21 +5,17 @@
#include "util.h" #include "util.h"
typedef struct Type { enum Type {
enum { TypeVoid = 0,
TypeVoid = 0, TypeFloat,
TypeFloat, TypeInt,
TypeInt, TypeBool,
TypeBool, TypeChar,
TypeChar, TypePtr,
TypePtr, TypeArr,
TypeArr, TypeEnumSize,
TypeEnumSize, };
} kind; typedef enum Type Type;
/*union {
};*/
} Type;
extern size_t type_size[TypeEnumSize]; extern size_t type_size[TypeEnumSize];
extern const char *type_str[TypeEnumSize]; extern const char *type_str[TypeEnumSize];
@ -38,8 +34,8 @@ typedef struct Value {
struct Value *val; struct Value *val;
} Ptr; } Ptr;
struct { struct {
bool is_string : 1;
Type type; Type type;
bool is_string : 1;
void *vals; void *vals;
size_t len, cap; size_t len, cap;
} Arr; } Arr;

4
vm.c
View File

@ -67,9 +67,9 @@ void run(const IRToks *ir, const BuiltinFunc *builtin_funcs) {
} }
Value *v = &s.mem[instr->Unary.val.Addr]; Value *v = &s.mem[instr->Unary.val.Addr];
s.mem[instr->Unary.addr] = (Value){ s.mem[instr->Unary.addr] = (Value){
.type.kind = TypePtr, .type = TypePtr,
.Ptr = { .Ptr = {
.type.kind = v->type.kind, .type = v->type,
.val = v, .val = v,
}, },
}; };