Compare commits
No commits in common. "99489dfeb64f8c8cd202d675c50e65c14fde9b0b" and "6f91a71306b487ce4da7b291b66d2ea2cc0872ef" have entirely different histories.
99489dfeb6
...
6f91a71306
20
ir.c
20
ir.c
@ -21,7 +21,6 @@ const char *irinstr_str[IRInstrEnumSize] = {
|
|||||||
[IRJnz] = "jnz",
|
[IRJnz] = "jnz",
|
||||||
[IRCallInternal] = "calli",
|
[IRCallInternal] = "calli",
|
||||||
[IRAddrOf] = "addrof",
|
[IRAddrOf] = "addrof",
|
||||||
[IRArrMake] = "mkarr",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IRLIST_INIT_CAP_LONG 4096
|
#define IRLIST_INIT_CAP_LONG 4096
|
||||||
@ -87,16 +86,13 @@ void irlist_term(IRList *v) {
|
|||||||
case IRJnz:
|
case IRJnz:
|
||||||
free_irparam(&i->tok.CJmp.condition, true);
|
free_irparam(&i->tok.CJmp.condition, true);
|
||||||
break;
|
break;
|
||||||
case IRCallInternal:
|
case IRCallInternal: {
|
||||||
for (size_t j = 0; j < i->tok.CallI.n_args; j++)
|
size_t n_args = i->tok.CallI.n_args;
|
||||||
|
for (size_t j = 0; j < n_args; j++)
|
||||||
free_irparam(&i->tok.CallI.args[j], true);
|
free_irparam(&i->tok.CallI.args[j], true);
|
||||||
free(i->tok.CallI.args);
|
free(i->tok.CallI.args);
|
||||||
break;
|
break;
|
||||||
case IRArrMake:
|
}
|
||||||
for (size_t j = 0; j < i->tok.ArrMake.len; j++)
|
|
||||||
free_irparam(&i->tok.ArrMake.vals[j], true);
|
|
||||||
free(i->tok.ArrMake.vals);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
ASSERT_UNREACHED();
|
ASSERT_UNREACHED();
|
||||||
}
|
}
|
||||||
@ -202,14 +198,6 @@ void print_ir(IRList *v, const BuiltinFunc *builtin_funcs) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IRArrMake: {
|
|
||||||
printf(" %%%zx", i->tok.ArrMake.arr_addr);
|
|
||||||
for (size_t j = 0; j < i->tok.ArrMake.len; j++) {
|
|
||||||
printf(" ");
|
|
||||||
print_irparam(&i->tok.ArrMake.vals[j]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: ASSERT_UNREACHED();
|
default: ASSERT_UNREACHED();
|
||||||
}
|
}
|
||||||
printf(" ; %zu:%zu", i->tok.ln, i->tok.col);
|
printf(" ; %zu:%zu", i->tok.ln, i->tok.col);
|
||||||
|
7
ir.h
7
ir.h
@ -51,7 +51,6 @@ enum IRInstr {
|
|||||||
IRJnz,
|
IRJnz,
|
||||||
IRCallInternal,
|
IRCallInternal,
|
||||||
IRAddrOf,
|
IRAddrOf,
|
||||||
IRArrMake,
|
|
||||||
IRInstrEnumSize,
|
IRInstrEnumSize,
|
||||||
};
|
};
|
||||||
typedef enum IRInstr IRInstr;
|
typedef enum IRInstr IRInstr;
|
||||||
@ -107,12 +106,6 @@ typedef struct IRTok {
|
|||||||
size_t n_args;
|
size_t n_args;
|
||||||
IRParam *args;
|
IRParam *args;
|
||||||
} CallI;
|
} CallI;
|
||||||
|
|
||||||
struct {
|
|
||||||
size_t arr_addr;
|
|
||||||
size_t len, cap;
|
|
||||||
IRParam *vals;
|
|
||||||
} ArrMake;
|
|
||||||
};
|
};
|
||||||
} IRTok;
|
} IRTok;
|
||||||
|
|
||||||
|
7
lex.c
7
lex.c
@ -247,8 +247,6 @@ TokList lex(const char *s) {
|
|||||||
case '}':
|
case '}':
|
||||||
case '(':
|
case '(':
|
||||||
case ')':
|
case ')':
|
||||||
case '[':
|
|
||||||
case ']':
|
|
||||||
case ',':
|
case ',':
|
||||||
case '+':
|
case '+':
|
||||||
case '-':
|
case '-':
|
||||||
@ -299,7 +297,7 @@ TokList lex(const char *s) {
|
|||||||
consume(&pos, *(s++));
|
consume(&pos, *(s++));
|
||||||
c = get_esc_char(s[0]);
|
c = get_esc_char(s[0]);
|
||||||
if (!c) {
|
if (!c) {
|
||||||
set_err("Unrecognized escape sequence: '\\%c'", s[0]);
|
set_err("Unrecognized escape sequence: '\\%c'", c);
|
||||||
return toks;
|
return toks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -338,8 +336,7 @@ TokList lex(const char *s) {
|
|||||||
consume(&pos, *(s++));
|
consume(&pos, *(s++));
|
||||||
c = get_esc_char(s[0]);
|
c = get_esc_char(s[0]);
|
||||||
if (!c) {
|
if (!c) {
|
||||||
set_err("Unrecognized escape sequence: '\\%c'", s[0]);
|
set_err("Unrecognized escape sequence: '\\%c'", c);
|
||||||
free(str);
|
|
||||||
return toks;
|
return toks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
100
parse.c
100
parse.c
@ -66,9 +66,6 @@ static void set_irtok_dest_addr(IRTok *t, size_t addr) {
|
|||||||
case IRCallInternal:
|
case IRCallInternal:
|
||||||
t->CallI.ret_addr = addr;
|
t->CallI.ret_addr = addr;
|
||||||
break;
|
break;
|
||||||
case IRArrMake:
|
|
||||||
t->ArrMake.arr_addr = addr;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
ASSERT_UNREACHED();
|
ASSERT_UNREACHED();
|
||||||
}
|
}
|
||||||
@ -316,7 +313,7 @@ static ExprRet expr(IRList *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
|
|||||||
eval_func_in_place = false;
|
eval_func_in_place = false;
|
||||||
if (t->next->tok.kind == TokOp) {
|
if (t->next->tok.kind == TokOp) {
|
||||||
if (t->next->tok.Op == OpComma) {
|
if (t->next->tok.Op == OpComma) {
|
||||||
toklist_del(toks, t->next, t->next); /* delete comma */
|
toklist_del(toks, t->next, t->next); /* delete right parenthesis */
|
||||||
continue;
|
continue;
|
||||||
} else if (t->next->tok.Op == OpRParen) {
|
} else if (t->next->tok.Op == OpRParen) {
|
||||||
toklist_del(toks, t->next, t->next); /* delete right parenthesis */
|
toklist_del(toks, t->next, t->next); /* delete right parenthesis */
|
||||||
@ -397,99 +394,6 @@ static ExprRet expr(IRList *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Collapse array. */
|
|
||||||
else if (t->tok.kind == TokOp && t->tok.Op == OpLBrack) {
|
|
||||||
TokListItem *lbrack = t;
|
|
||||||
bool eval_immediately = true;
|
|
||||||
size_t elems_len = 0;
|
|
||||||
size_t elems_cap = 0;
|
|
||||||
IRParam *elems = NULL;
|
|
||||||
|
|
||||||
if (t->next->tok.kind == TokOp && t->next->tok.Op == OpRBrack) {
|
|
||||||
/* empty array */
|
|
||||||
toklist_del(toks, t->next, t->next); /* delete right bracket */
|
|
||||||
} else {
|
|
||||||
elems_cap = 16;
|
|
||||||
elems = xmalloc(sizeof(IRParam) * elems_cap);
|
|
||||||
for (;;) {
|
|
||||||
if (elems_len+1 > elems_cap)
|
|
||||||
elems = xrealloc(elems, (elems_cap *= 2));
|
|
||||||
IRParam e;
|
|
||||||
TRY_RET_ELSE(e = expr_into_irparam(out_ir, toks, funcs, &sc, t->next), (ExprRet){0}, free(elems));
|
|
||||||
if (e.kind != IRParamLiteral)
|
|
||||||
eval_immediately = false;
|
|
||||||
elems[elems_len++] = e;
|
|
||||||
if (t->next->tok.kind == TokOp) {
|
|
||||||
if (t->next->tok.Op == OpComma) {
|
|
||||||
toklist_del(toks, t->next, t->next); /* delete comma */
|
|
||||||
continue;
|
|
||||||
} else if (t->next->tok.Op == OpRBrack) {
|
|
||||||
toklist_del(toks, t->next, t->next); /* delete right bracket */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mark_err(&t->next->tok);
|
|
||||||
set_err("Expected ',' or ']' after array element");
|
|
||||||
free(elems);
|
|
||||||
return (ExprRet){0};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eval_immediately) {
|
|
||||||
/* turn array into value */
|
|
||||||
Value arr = {
|
|
||||||
.type = TypeArr,
|
|
||||||
.Arr = {
|
|
||||||
.type = TypeVoid,
|
|
||||||
.is_string = false,
|
|
||||||
.dynamically_allocated = false,
|
|
||||||
.vals = NULL,
|
|
||||||
.len = elems_len,
|
|
||||||
.cap = elems_len ? elems_cap : 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if (elems_len) {
|
|
||||||
Type arr_ty = elems[0].Literal.type;
|
|
||||||
void *arr_vals = xmalloc(type_size[arr_ty] * elems_cap);
|
|
||||||
for (size_t i = 0; i < elems_len; i++) {
|
|
||||||
Value *v = &elems[i].Literal;
|
|
||||||
if (v->type != arr_ty) {
|
|
||||||
set_err("Type of array item %zu (%s) differs from array type (%s)", i, type_str[v->type], type_str[arr_ty]);
|
|
||||||
free(arr_vals);
|
|
||||||
free(elems);
|
|
||||||
return (ExprRet){0};
|
|
||||||
}
|
|
||||||
memcpy((uint8_t*)arr_vals + type_size[arr_ty] * i, &v->Void, type_size[arr_ty]);
|
|
||||||
}
|
|
||||||
arr.Arr.type = arr_ty;
|
|
||||||
arr.Arr.vals = arr_vals;
|
|
||||||
}
|
|
||||||
/* set lbracket to collapsed array value */
|
|
||||||
lbrack->tok.kind = TokVal;
|
|
||||||
lbrack->tok.Val = arr;
|
|
||||||
/* free the now no longer needed element IRParam values */
|
|
||||||
free(elems);
|
|
||||||
} else {
|
|
||||||
/* array initialization IR instruction */
|
|
||||||
IRTok ir_tok = {
|
|
||||||
.ln = lbrack->tok.ln,
|
|
||||||
.col = lbrack->tok.col,
|
|
||||||
.instr = IRArrMake,
|
|
||||||
.ArrMake = {
|
|
||||||
.arr_addr = 0,
|
|
||||||
.len = elems_len,
|
|
||||||
.cap = elems_cap,
|
|
||||||
.vals = elems,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/* return if we've just evaluated the last instruction */
|
|
||||||
ExprRet ret;
|
|
||||||
if (expr_flush_ir_and_maybe_return(out_ir, toks, ir_tok, start, &sc, lbrack, &ret))
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Collapse unary operation. */
|
/* Collapse unary operation. */
|
||||||
if (perform_unary) {
|
if (perform_unary) {
|
||||||
Tok *v = &t->tok; /* what we want to perform the operation on */
|
Tok *v = &t->tok; /* what we want to perform the operation on */
|
||||||
@ -729,9 +633,9 @@ static void stmt(IRList *out_ir, TokList *toks, Map *funcs, Scope *sc, TokListIt
|
|||||||
skip_newlns(toks, t->next);
|
skip_newlns(toks, t->next);
|
||||||
if (t->next->tok.kind == TokOp) {
|
if (t->next->tok.kind == TokOp) {
|
||||||
if (t->next->tok.Op == OpEOF) {
|
if (t->next->tok.Op == OpEOF) {
|
||||||
|
term_scope(&inner_sc);
|
||||||
mark_err(&start->tok);
|
mark_err(&start->tok);
|
||||||
set_err("Unclosed '{'");
|
set_err("Unclosed '{'");
|
||||||
term_scope(&inner_sc);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (t->next->tok.Op == OpRCurl)
|
if (t->next->tok.Op == OpRCurl)
|
||||||
|
3
tok.c
3
tok.c
@ -117,7 +117,6 @@ int8_t op_prec[OperatorEnumSize] = {
|
|||||||
[OpNewLn] = PREC_DELIM,
|
[OpNewLn] = PREC_DELIM,
|
||||||
[OpLCurl] = PREC_DELIM,
|
[OpLCurl] = PREC_DELIM,
|
||||||
[OpRParen] = PREC_DELIM,
|
[OpRParen] = PREC_DELIM,
|
||||||
[OpRBrack] = PREC_DELIM,
|
|
||||||
[OpComma] = PREC_DELIM,
|
[OpComma] = PREC_DELIM,
|
||||||
[OpAnd] = 0,
|
[OpAnd] = 0,
|
||||||
[OpOr] = 0,
|
[OpOr] = 0,
|
||||||
@ -138,8 +137,6 @@ const char *op_str[OperatorEnumSize] = {
|
|||||||
[OpRCurl] = "}",
|
[OpRCurl] = "}",
|
||||||
[OpLParen] = "(",
|
[OpLParen] = "(",
|
||||||
[OpRParen] = ")",
|
[OpRParen] = ")",
|
||||||
[OpLBrack] = "[",
|
|
||||||
[OpRBrack] = "]",
|
|
||||||
[OpComma] = ",",
|
[OpComma] = ",",
|
||||||
[OpAdd] = "+",
|
[OpAdd] = "+",
|
||||||
[OpSub] = "-",
|
[OpSub] = "-",
|
||||||
|
2
tok.h
2
tok.h
@ -51,8 +51,6 @@ enum Operator {
|
|||||||
OpRCurl = '}',
|
OpRCurl = '}',
|
||||||
OpLParen = '(',
|
OpLParen = '(',
|
||||||
OpRParen = ')',
|
OpRParen = ')',
|
||||||
OpLBrack = '[',
|
|
||||||
OpRBrack = ']',
|
|
||||||
OpComma = ',',
|
OpComma = ',',
|
||||||
OpAdd = '+',
|
OpAdd = '+',
|
||||||
OpSub = '-',
|
OpSub = '-',
|
||||||
|
35
vm.c
35
vm.c
@ -93,8 +93,6 @@ void run(IRList *ir, const BuiltinFunc *builtin_funcs) {
|
|||||||
case IRAddrOf: {
|
case IRAddrOf: {
|
||||||
if (instr->Unary.val.kind != IRParamAddr) {
|
if (instr->Unary.val.kind != IRParamAddr) {
|
||||||
set_err("Unable to take the address of a literal");
|
set_err("Unable to take the address of a literal");
|
||||||
free(fn_args);
|
|
||||||
stack_term(&s);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Value *v = &s.mem[instr->Unary.val.Addr];
|
Value *v = &s.mem[instr->Unary.val.Addr];
|
||||||
@ -176,39 +174,6 @@ void run(IRList *ir, const BuiltinFunc *builtin_funcs) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IRArrMake: {
|
|
||||||
size_t arr_len = instr->ArrMake.len, arr_cap = instr->ArrMake.cap;
|
|
||||||
Value arr = {
|
|
||||||
.type = TypeArr,
|
|
||||||
.Arr = {
|
|
||||||
.type = TypeVoid,
|
|
||||||
.is_string = false,
|
|
||||||
.dynamically_allocated = true,
|
|
||||||
.vals = NULL,
|
|
||||||
.len = arr_len,
|
|
||||||
.cap = arr_len ? arr_cap : 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if (arr_len) {
|
|
||||||
Type arr_ty = irparam_to_val(&s, &instr->ArrMake.vals[0])->type;
|
|
||||||
void *arr_vals = xmalloc(type_size[arr_ty] * arr_cap);
|
|
||||||
for (size_t j = 0; j < arr_len; j++) {
|
|
||||||
Value *v = irparam_to_val(&s, &instr->ArrMake.vals[j]);
|
|
||||||
if (v->type != arr_ty) {
|
|
||||||
set_err("Type of array item %zu (%s) differs from array type (%s)", j, type_str[v->type], type_str[arr_ty]);
|
|
||||||
free(arr_vals);
|
|
||||||
free(fn_args);
|
|
||||||
stack_term(&s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memcpy((uint8_t*)arr_vals + type_size[arr_ty] * j, &v->Void, type_size[arr_ty]);
|
|
||||||
}
|
|
||||||
arr.Arr.type = arr_ty;
|
|
||||||
arr.Arr.vals = arr_vals;
|
|
||||||
}
|
|
||||||
stack_assign(&s, instr->ArrMake.arr_addr, &arr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
ASSERT_UNREACHED();
|
ASSERT_UNREACHED();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user