summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/compiler.lm137
1 files changed, 49 insertions, 88 deletions
diff --git a/src/compiler/compiler.lm b/src/compiler/compiler.lm
index 502422d..28e7f96 100644
--- a/src/compiler/compiler.lm
+++ b/src/compiler/compiler.lm
@@ -241,7 +241,6 @@ lookup(type:str, name:str, s:scope)
global g_cscope:map<any, scope> = new map<any, scope>()
global g_regs:map<any, int> = new map<any, int>()
-global g_offs:map<any, int> = new map<any, int>()
global g_ops:map<str, int> = new map<str, int>()
global g_visuals:map<str, int> = new map<str, int>()
global g_types:map<str, int> = new map<str, int>()
@@ -283,22 +282,19 @@ global INS_REG:int = 1
global INS_PUSH:int = 2
global INS_PUSHR:int = 3
global INS_POP:int = 4
-global INS_INCR:int = 5
-global INS_OP:int = 6
-global INS_QUEUE:int = 7
-global INS_IO:int = 8
-global INS_EXEC:int = 9
-global INS_CALL:int = 10
-global INS_JMP:int = 11
-global INS_JMPIF:int = 12
+global INS_OP:int = 5
+global INS_QUEUE:int = 6
+global INS_IO:int = 7
+global INS_CALL:int = 8
+global INS_JMP:int = 9
+global INS_JMPIF:int = 10
int insbuf_written() = c_insbuf_written
str flush_insbuf() = c_flush_insbuf
void write_ins(ins:int, num:int) = c_write_ins
void write_ins_with_data(ins:int, data:str) = c_write_ins_with_data
-global g_r1:int = 1
-global g_regc:int = g_r1 + 1
+global g_regc:int = 1
void
new_reg(v:any, data:str)
@@ -334,6 +330,11 @@ find_data_in(s:any)
write_ins(INS_VERSION, 1)
write_ins_with_data(INS_REG, '')
+for d:fspec::declaration::type in source {
+ if (d.primitive)
+ new_reg(%d, nil)
+}
+
for e:expr::paren::type in source
find_data_in(e.collapsed)
for e:expr::bracket::type in source
@@ -343,12 +344,14 @@ for e:expr::arg::type in source
for f:reference::function::type in source
write_data_if_not_there($f.name)
for d:fspec::declaration::type in source {
- if (d.name)
- write_data_if_not_there($d.name)
if (d.container && d.container.data.name)
write_data_if_not_there($d.container.data.name)
+ if (d.name)
+ write_data_if_not_there($d.name)
}
+print("ASD\n")
+
void
write_expr(expr:collapser::reducer::collapsed)
{
@@ -377,12 +380,10 @@ write_expr(expr:collapser::reducer::collapsed)
off:int = 0
for r:reference::variable::type in vop {
d = lookup('variable', $r.name, s)
- if (d.container) {
+ if (d.container)
s = g_cscope->find(%d.container)
- off = g_offs->find(%d.container)
- }
}
- write_ins(INS_PUSHR, off + g_regs->find(%d) - off)
+ write_ins(INS_PUSHR, g_regs->find(%d))
} else {
write_ins(INS_OP, g_ops->find($vop.op))
}
@@ -418,9 +419,6 @@ write_declaration(d:fspec::declaration::type, index:int)
c:fspec::container::type = d.container
if (d.cref) c = lookup($d.cref, $d.parent, nil)
- if (!c && index > 0)
- write_ins(INS_INCR, g_r1)
-
locs:map<any, int> = new map<any, int>()
if (d.extra) {
for l:fspec::declaration::dimension in repeat(d.extra.dimension) {
@@ -436,10 +434,19 @@ write_declaration(d:fspec::declaration::type, index:int)
}
if (!c) {
+ write_ins(INS_PUSH, index)
write_ins(INS_IO, d.primitive.bits)
} else {
- write_ins(INS_PUSH, g_offs->find(%c))
- write_ins(INS_EXEC, g_regs->find(%c))
+ for i:fspec::container::strukt::item in repeat(d.container.data.items) {
+ if (i.data.name) {
+ write_declaration(i.data, index)
+ index = index + 1
+ } else if (i.data.function) {
+ for a:expr::arg::type in i.data.function
+ write_expr(a.collapsed.result)
+ write_ins(INS_CALL, g_regs->find($i.data.function.name))
+ }
+ }
}
if (d.extra) {
@@ -448,40 +455,8 @@ write_declaration(d:fspec::declaration::type, index:int)
}
}
-void
-walk1(d:fspec::declaration::type)
-{
- c:fspec::container::type = d.container
- if (d.cref) c = lookup($d.cref, $d.parent, nil)
-
- if (!c || !d.name)
- return 0
-
- for i:fspec::container::strukt::item in repeat(d.container.data.items)
- walk1(i.data)
-
- for i:fspec::container::select::item in repeat(d.container.data.items)
- walk1(i.data)
-
- g_offs->insert(%d, g_regc)
-
- for i:fspec::container::enum::item in repeat(d.container.data.items) {
- # somehow need to get this constant time (not reg)
- }
-
- for i:fspec::container::strukt::item in repeat(d.container.data.items) {
- if (i.data.primitive)
- new_reg(%i.data, nil)
- }
-
- for i:fspec::container::select::item in repeat(d.container.data.items) {
- if (i.data.primitive)
- new_reg(%i.data, nil)
- }
-}
-
-void
-walk2(d:fspec::declaration::type)
+int
+walk2(d:fspec::declaration::type, index:int)
{
if (!d.container) {
print('something went wrong!\n')
@@ -497,37 +472,22 @@ walk2(d:fspec::declaration::type)
insert('variable', $i.decl.name, %i.decl)
for i:fspec::container::strukt::item in repeat(d.container.data.items) {
- if (i.data.container)
- walk2(i.data)
- if (i.data.name)
- insert('variable', $i.data.name, %i.data)
- }
-
- for i:fspec::container::select::item in repeat(d.container.data.items) {
- if (i.data.container)
- walk2(i.data)
- if (i.data.name)
- insert('variable', $i.data.name, %i.data)
- }
-
- if (!d.name) {
- write_ins(INS_PUSH, g_offs->find(%d.container))
- write_ins(INS_POP, g_r1)
- }
-
- index:int = 0
- for i:fspec::container::strukt::item in repeat(d.container.data.items)
if (i.data.name) {
+ insert('variable', $i.data.name, %i.data)
write_declaration(i.data, index)
index = index + 1
} else if (i.data.function) {
for a:expr::arg::type in i.data.function
write_expr(a.collapsed.result)
write_ins(INS_CALL, g_regs->find($i.data.function.name))
+ } else if (i.data.container) {
+ index = walk2(i.data, index)
}
+ }
for i:fspec::container::select::item in repeat(d.container.data.items) {
if (i.data.name) {
+ insert('variable', $i.data.name, %i.data)
if (i.expr) {
write_expr(d.container.data.select.collapsed.result)
write_expr(i.expr.collapsed.result)
@@ -535,26 +495,27 @@ walk2(d:fspec::declaration::type)
}
write_declaration(i.data, index)
index = index + 1
+ } else if (i.data.container) {
+ index = walk2(i.data, index)
}
}
- if (insbuf_written()) {
- new_reg(%d.container, flush_insbuf())
- print(flush_insbuf())
- }
-
g_cscope->insert(%d, g_scopes->top)
if ($d.container.data.type != 'enum')
pop_scope()
-}
-for d:fspec::declaration::type in repeat(source.items)
- walk1(d)
+ return index
+}
push_scope()
-for d:fspec::declaration::type in repeat(source.items)
- walk2(d)
-pop_scope()
+index:int = 1
+for d:fspec::declaration::type in repeat(source.items) {
+ walk2(d, index)
-print(flush_insbuf())
+ if (insbuf_written()) {
+ write_ins_with_data(INS_REG, flush_insbuf())
+ print(flush_insbuf())
+ }
+}
+pop_scope()