Compare commits
No commits in common. "ca232fbf6a6c4adff629649db71011c1cb115c07" and "84785dc3cfae494cf9a503adc52bf5d4a23c9adc" have entirely different histories.
ca232fbf6a
...
84785dc3cf
8
ir.c
8
ir.c
@ -14,8 +14,6 @@ const char *irinstr_str[IRInstrEnumSize] = {
|
|||||||
[IRLt] = "lt",
|
[IRLt] = "lt",
|
||||||
[IRLe] = "le",
|
[IRLe] = "le",
|
||||||
[IRNot] = "not",
|
[IRNot] = "not",
|
||||||
[IRAnd] = "and",
|
|
||||||
[IROr] = "or",
|
|
||||||
[IRJmp] = "jmp",
|
[IRJmp] = "jmp",
|
||||||
[IRJnz] = "jnz",
|
[IRJnz] = "jnz",
|
||||||
[IRCallInternal] = "calli",
|
[IRCallInternal] = "calli",
|
||||||
@ -86,9 +84,6 @@ static void print_val(const Value *v) {
|
|||||||
case TypeBool:
|
case TypeBool:
|
||||||
printf("%s", v->Bool ? "true" : "false");
|
printf("%s", v->Bool ? "true" : "false");
|
||||||
break;
|
break;
|
||||||
case TypeChar:
|
|
||||||
printf("'%c'", v->Char);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
printf("(unknown type)");
|
printf("(unknown type)");
|
||||||
break;
|
break;
|
||||||
@ -110,7 +105,6 @@ void print_ir(IRToks *v, const BuiltinFunc *builtin_funcs) {
|
|||||||
switch (v->toks[i].instr) {
|
switch (v->toks[i].instr) {
|
||||||
case IRSet:
|
case IRSet:
|
||||||
case IRNeg:
|
case IRNeg:
|
||||||
case IRNot:
|
|
||||||
printf(" %%%zx ", v->toks[i].Unary.addr);
|
printf(" %%%zx ", v->toks[i].Unary.addr);
|
||||||
print_irparam(&v->toks[i].Unary.val);
|
print_irparam(&v->toks[i].Unary.val);
|
||||||
break;
|
break;
|
||||||
@ -121,8 +115,6 @@ void print_ir(IRToks *v, const BuiltinFunc *builtin_funcs) {
|
|||||||
case IREq:
|
case IREq:
|
||||||
case IRLt:
|
case IRLt:
|
||||||
case IRLe:
|
case IRLe:
|
||||||
case IRAnd:
|
|
||||||
case IROr:
|
|
||||||
printf(" %%%zx ", v->toks[i].Binary.addr);
|
printf(" %%%zx ", v->toks[i].Binary.addr);
|
||||||
print_irparam(&v->toks[i].Binary.lhs);
|
print_irparam(&v->toks[i].Binary.lhs);
|
||||||
printf(" ");
|
printf(" ");
|
||||||
|
2
ir.h
2
ir.h
@ -22,8 +22,6 @@ enum IRInstr {
|
|||||||
IRLt,
|
IRLt,
|
||||||
IRLe,
|
IRLe,
|
||||||
IRNot,
|
IRNot,
|
||||||
IRAnd,
|
|
||||||
IROr,
|
|
||||||
IRJmp,
|
IRJmp,
|
||||||
IRJnz,
|
IRJnz,
|
||||||
IRCallInternal,
|
IRCallInternal,
|
||||||
|
51
lex.c
51
lex.c
@ -11,7 +11,6 @@ static void consume(Pos *p, char c);
|
|||||||
static void emit(TokList *toks, const Pos *p, Tok t);
|
static void emit(TokList *toks, const Pos *p, Tok t);
|
||||||
static void mark(Pos *p);
|
static void mark(Pos *p);
|
||||||
static void mark_err(const Pos *p);
|
static void mark_err(const Pos *p);
|
||||||
static char get_esc_char(char c);
|
|
||||||
|
|
||||||
static void consume(Pos *p, char c) {
|
static void consume(Pos *p, char c) {
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
@ -37,23 +36,6 @@ static void mark_err(const Pos *p) {
|
|||||||
err_col = p->m_col;
|
err_col = p->m_col;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char get_esc_char(char c) {
|
|
||||||
switch(c) {
|
|
||||||
case 'a': return '\a';
|
|
||||||
case 'b': return '\b';
|
|
||||||
case 'e': return '\033';
|
|
||||||
case 'f': return '\f';
|
|
||||||
case 'n': return '\n';
|
|
||||||
case 'r': return '\r';
|
|
||||||
case 't': return '\t';
|
|
||||||
case 'v': return '\v';
|
|
||||||
case '\\': return '\\';
|
|
||||||
case '\'': return '\'';
|
|
||||||
case '"': return '\"';
|
|
||||||
default: return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TokList lex(const char *s) {
|
TokList lex(const char *s) {
|
||||||
TokList toks;
|
TokList toks;
|
||||||
toklist_init(&toks);
|
toklist_init(&toks);
|
||||||
@ -218,20 +200,6 @@ TokList lex(const char *s) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '&':
|
|
||||||
consume(&pos, *(s++));
|
|
||||||
if (s[0] == '&') {
|
|
||||||
emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpAnd });
|
|
||||||
} else
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
case '|':
|
|
||||||
consume(&pos, *(s++));
|
|
||||||
if (s[0] == '|') {
|
|
||||||
emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpOr });
|
|
||||||
} else
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
case '{':
|
case '{':
|
||||||
case '}':
|
case '}':
|
||||||
case '(':
|
case '(':
|
||||||
@ -280,25 +248,6 @@ TokList lex(const char *s) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case '\'': {
|
|
||||||
consume(&pos, *(s++));
|
|
||||||
char c = s[0];
|
|
||||||
if (c == '\\') {
|
|
||||||
consume(&pos, *(s++));
|
|
||||||
c = get_esc_char(s[0]);
|
|
||||||
if (!c) {
|
|
||||||
set_err("Unrecognized escape sequence: '\\%c'", c);
|
|
||||||
return toks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
consume(&pos, *(s++));
|
|
||||||
if (s[0] != '\'') {
|
|
||||||
set_err("Unclosed char literal");
|
|
||||||
return toks;
|
|
||||||
}
|
|
||||||
emit(&toks, &pos, (Tok){ .kind = TokVal, .Val = { .type = { .kind = TypeChar, }, .Char = c, }, });
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
set_err("Unrecognized character: '%c'", s[0]);
|
set_err("Unrecognized character: '%c'", s[0]);
|
||||||
return toks;
|
return toks;
|
||||||
|
18
main.c
18
main.c
@ -33,25 +33,18 @@ static void die(const char *fmt, ...) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Value fn_put(Value *args) {
|
static Value fn_print(Value *args) {
|
||||||
switch (args[0].type.kind) {
|
switch (args[0].type.kind) {
|
||||||
case TypeVoid: printf("(void)"); break;
|
case TypeVoid: printf("(void)\n"); break;
|
||||||
case TypeFloat: printf("%f", args[0].Float); break;
|
case TypeFloat: printf("%f\n", args[0].Float); break;
|
||||||
case TypeInt: printf("%zd", args[0].Int); break;
|
case TypeInt: printf("%zd\n", args[0].Int); break;
|
||||||
case TypeBool: printf("%s", args[0].Bool ? "true" : "false"); break;
|
case TypeBool: printf("%s\n", args[0].Bool ? "true" : "false"); break;
|
||||||
case TypeChar: printf("%c", args[0].Char); break;
|
|
||||||
default:
|
default:
|
||||||
ASSERT_UNREACHED();
|
ASSERT_UNREACHED();
|
||||||
}
|
}
|
||||||
return (Value){0};
|
return (Value){0};
|
||||||
}
|
}
|
||||||
|
|
||||||
static Value fn_print(Value *args) {
|
|
||||||
fn_put(args);
|
|
||||||
printf("\n");
|
|
||||||
return (Value){0};
|
|
||||||
}
|
|
||||||
|
|
||||||
static Value fn_int(Value *args) {
|
static Value fn_int(Value *args) {
|
||||||
Value ret = {
|
Value ret = {
|
||||||
.type.kind = TypeInt,
|
.type.kind = TypeInt,
|
||||||
@ -148,7 +141,6 @@ int main(int argc, const char **argv) {
|
|||||||
print_toks(&tokens);
|
print_toks(&tokens);
|
||||||
/* parse tokens into IR code */
|
/* parse tokens into IR code */
|
||||||
BuiltinFunc funcs[] = {
|
BuiltinFunc funcs[] = {
|
||||||
{ .name = "put", .side_effects = true, .n_args = 1, .func = fn_put, },
|
|
||||||
{ .name = "print", .side_effects = true, .n_args = 1, .func = fn_print, },
|
{ .name = "print", .side_effects = true, .n_args = 1, .func = fn_print, },
|
||||||
{ .name = "int", .side_effects = false, .n_args = 1, .func = fn_int, },
|
{ .name = "int", .side_effects = false, .n_args = 1, .func = fn_int, },
|
||||||
{ .name = "float", .side_effects = false, .n_args = 1, .func = fn_float, },
|
{ .name = "float", .side_effects = false, .n_args = 1, .func = fn_float, },
|
||||||
|
@ -1,87 +0,0 @@
|
|||||||
width := 280
|
|
||||||
height := 100
|
|
||||||
|
|
||||||
iterations := 100
|
|
||||||
xmin := -2.0
|
|
||||||
xmax := 0.5
|
|
||||||
ymin := -1.0
|
|
||||||
ymax := 1.0
|
|
||||||
|
|
||||||
// Some further coordinates:
|
|
||||||
/*iterations := 1000
|
|
||||||
xmin := -0.9072945999
|
|
||||||
xmax := -0.8984310833
|
|
||||||
ymin := 0.2304178999
|
|
||||||
ymax := 0.2370858666*/
|
|
||||||
|
|
||||||
/*iterations := 100
|
|
||||||
xmin := -0.193596288
|
|
||||||
xmax := -0.119260320
|
|
||||||
ymin := 1.006960992
|
|
||||||
ymax := 1.062687264*/
|
|
||||||
|
|
||||||
/*iterations := 800
|
|
||||||
xmin := -0.1675326254
|
|
||||||
xmax := -0.1675148625
|
|
||||||
ymin := 1.0413005672
|
|
||||||
ymax := 1.0413138086*/
|
|
||||||
|
|
||||||
/*iterations := 918
|
|
||||||
xmin := -0.7506201104
|
|
||||||
xmax := -0.7503409687
|
|
||||||
ymin := 0.0170447020
|
|
||||||
ymax := 0.0172540583*/
|
|
||||||
|
|
||||||
/*iterations := 400
|
|
||||||
xmin := -0.7548484315
|
|
||||||
xmax := -0.7540548595
|
|
||||||
ymin := 0.0530077004
|
|
||||||
ymax := 0.0536039518*/
|
|
||||||
|
|
||||||
y := 0
|
|
||||||
while y < height {
|
|
||||||
c_im := (float(height - y) / float(height)) * (ymax - ymin) + ymin
|
|
||||||
x := 0
|
|
||||||
while x < width {
|
|
||||||
c_re := (float(x) / float(width)) * (xmax - xmin) + xmin
|
|
||||||
|
|
||||||
z_re := 0.0
|
|
||||||
z_im := 0.0
|
|
||||||
|
|
||||||
it := 0
|
|
||||||
loop := true
|
|
||||||
while it < iterations && loop {
|
|
||||||
/* z = z*z + c */
|
|
||||||
/* (a + bi)^2 = a^2 + 2abi - b^2 */
|
|
||||||
z_re_tmp := z_re * z_re - z_im * z_im + c_re
|
|
||||||
z_im = 2.0 * z_re * z_im + c_im
|
|
||||||
z_re = z_re_tmp
|
|
||||||
|
|
||||||
/* Break if the number shoots off to infinity. */
|
|
||||||
if z_re * z_re + z_im * z_im > 4.0 {
|
|
||||||
loop = false
|
|
||||||
}
|
|
||||||
|
|
||||||
it = it + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if it <= iterations / 5 {
|
|
||||||
put(' ')
|
|
||||||
} else if it <= iterations / 5 * 2 {
|
|
||||||
put('.')
|
|
||||||
} else if it <= iterations / 5 * 3 {
|
|
||||||
put(',')
|
|
||||||
} else if it <= iterations / 5 * 4 {
|
|
||||||
put('*')
|
|
||||||
} else if it < iterations {
|
|
||||||
put('+')
|
|
||||||
} else if it == iterations {
|
|
||||||
put('#')
|
|
||||||
}
|
|
||||||
|
|
||||||
x = x + 1
|
|
||||||
}
|
|
||||||
put('\n')
|
|
||||||
|
|
||||||
y = y + 1
|
|
||||||
}
|
|
4
parse.c
4
parse.c
@ -56,8 +56,6 @@ static void set_irtok_dest_addr(IRTok *t, size_t addr) {
|
|||||||
case IREq:
|
case IREq:
|
||||||
case IRLt:
|
case IRLt:
|
||||||
case IRLe:
|
case IRLe:
|
||||||
case IRAnd:
|
|
||||||
case IROr:
|
|
||||||
t->Binary.addr = addr;
|
t->Binary.addr = addr;
|
||||||
break;
|
break;
|
||||||
case IRCallInternal:
|
case IRCallInternal:
|
||||||
@ -448,8 +446,6 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
|
|||||||
case OpLe: instr = IRLe; break;
|
case OpLe: instr = IRLe; break;
|
||||||
case OpGt: instr = IRLt; swap_operands = true; break;
|
case OpGt: instr = IRLt; swap_operands = true; break;
|
||||||
case OpGe: instr = IRLe; swap_operands = true; break;
|
case OpGe: instr = IRLe; swap_operands = true; break;
|
||||||
case OpAnd: instr = IRAnd; break;
|
|
||||||
case OpOr: instr = IROr; break;
|
|
||||||
default:
|
default:
|
||||||
mark_err(l_op);
|
mark_err(l_op);
|
||||||
set_err("Unknown operation: '%s'", op_str[l_op->Op]);
|
set_err("Unknown operation: '%s'", op_str[l_op->Op]);
|
||||||
|
12
runtime.c
12
runtime.c
@ -65,18 +65,6 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
|
|||||||
.type.kind = TypeBool,
|
.type.kind = TypeBool,
|
||||||
.Bool = res,
|
.Bool = res,
|
||||||
};
|
};
|
||||||
case IRAnd:
|
|
||||||
return (Value){
|
|
||||||
.type.kind = TypeBool,
|
|
||||||
.Bool = is_nonzero(lhs) && is_nonzero(rhs),
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case IROr:
|
|
||||||
return (Value){
|
|
||||||
.type.kind = TypeBool,
|
|
||||||
.Bool = is_nonzero(lhs) || is_nonzero(rhs),
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
ASSERT_UNREACHED();
|
ASSERT_UNREACHED();
|
||||||
}
|
}
|
||||||
|
25
tok.c
25
tok.c
@ -11,17 +11,15 @@ int8_t op_prec[OperatorEnumSize] = {
|
|||||||
[OpLCurl] = PREC_DELIM,
|
[OpLCurl] = PREC_DELIM,
|
||||||
[OpRParen] = PREC_DELIM,
|
[OpRParen] = PREC_DELIM,
|
||||||
[OpComma] = PREC_DELIM,
|
[OpComma] = PREC_DELIM,
|
||||||
[OpAnd] = 0,
|
[OpEq] = 0,
|
||||||
[OpOr] = 0,
|
[OpLt] = 0,
|
||||||
[OpEq] = 1,
|
[OpGt] = 0,
|
||||||
[OpLt] = 1,
|
[OpLe] = 0,
|
||||||
[OpGt] = 1,
|
[OpGe] = 0,
|
||||||
[OpLe] = 1,
|
[OpAdd] = 1,
|
||||||
[OpGe] = 1,
|
[OpSub] = 1,
|
||||||
[OpAdd] = 2,
|
[OpMul] = 2,
|
||||||
[OpSub] = 2,
|
[OpDiv] = 2,
|
||||||
[OpMul] = 3,
|
|
||||||
[OpDiv] = 3,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *op_str[OperatorEnumSize] = {
|
const char *op_str[OperatorEnumSize] = {
|
||||||
@ -42,8 +40,6 @@ const char *op_str[OperatorEnumSize] = {
|
|||||||
[OpGt] = ">",
|
[OpGt] = ">",
|
||||||
[OpLe] = "<=",
|
[OpLe] = "<=",
|
||||||
[OpGe] = ">=",
|
[OpGe] = ">=",
|
||||||
[OpAnd] = "&&",
|
|
||||||
[OpOr] = "||",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *tok_str[TokKindEnumSize] = {
|
const char *tok_str[TokKindEnumSize] = {
|
||||||
@ -119,9 +115,6 @@ void print_toks(TokList *l) {
|
|||||||
case TypeBool:
|
case TypeBool:
|
||||||
printf(": " C_ICYAN "%s" C_RESET, i->tok.Val.Bool ? "true" : "false");
|
printf(": " C_ICYAN "%s" C_RESET, i->tok.Val.Bool ? "true" : "false");
|
||||||
break;
|
break;
|
||||||
case TypeChar:
|
|
||||||
printf(": " C_ICYAN "'%c'" C_RESET, i->tok.Val.Char);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
printf(" " C_ICYAN "(unknown type)" C_RESET);
|
printf(" " C_ICYAN "(unknown type)" C_RESET);
|
||||||
break;
|
break;
|
||||||
|
4
tok.h
4
tok.h
@ -12,7 +12,6 @@ typedef struct Type {
|
|||||||
TypeFloat,
|
TypeFloat,
|
||||||
TypeInt,
|
TypeInt,
|
||||||
TypeBool,
|
TypeBool,
|
||||||
TypeChar,
|
|
||||||
} kind;
|
} kind;
|
||||||
|
|
||||||
/*union {
|
/*union {
|
||||||
@ -26,7 +25,6 @@ typedef struct Value {
|
|||||||
double Float;
|
double Float;
|
||||||
ssize_t Int;
|
ssize_t Int;
|
||||||
bool Bool;
|
bool Bool;
|
||||||
char Char;
|
|
||||||
};
|
};
|
||||||
} Value;
|
} Value;
|
||||||
|
|
||||||
@ -47,8 +45,6 @@ enum Operator {
|
|||||||
OpGt,
|
OpGt,
|
||||||
OpLe,
|
OpLe,
|
||||||
OpGe,
|
OpGe,
|
||||||
OpAnd,
|
|
||||||
OpOr,
|
|
||||||
OpNewLn,
|
OpNewLn,
|
||||||
OpEOF,
|
OpEOF,
|
||||||
OperatorEnumSize,
|
OperatorEnumSize,
|
||||||
|
2
vm.c
2
vm.c
@ -67,8 +67,6 @@ void run(const IRToks *ir, const BuiltinFunc *builtin_funcs) {
|
|||||||
case IREq:
|
case IREq:
|
||||||
case IRLt:
|
case IRLt:
|
||||||
case IRLe:
|
case IRLe:
|
||||||
case IRAnd:
|
|
||||||
case IROr:
|
|
||||||
stack_fit(&s, instr->Binary.addr);
|
stack_fit(&s, instr->Binary.addr);
|
||||||
TRY_ELSE(s.mem[instr->Binary.addr] = eval_binary(instr->instr,
|
TRY_ELSE(s.mem[instr->Binary.addr] = eval_binary(instr->instr,
|
||||||
irparam_to_val(&s, &instr->Binary.lhs),
|
irparam_to_val(&s, &instr->Binary.lhs),
|
||||||
|
Loading…
Reference in New Issue
Block a user