From eae3c68b51f0c2da861b4c0b87188d3bfb132f67 Mon Sep 17 00:00:00 2001 From: User <> Date: Tue, 28 Nov 2017 16:39:02 +0100 Subject: [PATCH] move boolean output and character input to subroutine, change memlib comments --- src/pp/s1184725/boppi/BoppiGenerator.java | 153 +++++++--------------- src/pp/s1184725/boppi/memlib.iloc | 12 +- src/pp/s1184725/boppi/stdlib.iloc | 39 ++++++ 3 files changed, 90 insertions(+), 114 deletions(-) create mode 100644 src/pp/s1184725/boppi/stdlib.iloc diff --git a/src/pp/s1184725/boppi/BoppiGenerator.java b/src/pp/s1184725/boppi/BoppiGenerator.java index 1ef800c..8c45d70 100644 --- a/src/pp/s1184725/boppi/BoppiGenerator.java +++ b/src/pp/s1184725/boppi/BoppiGenerator.java @@ -87,6 +87,15 @@ public class BoppiGenerator extends BoppiBaseVisitor { try { String memlib = new String(Files.readAllBytes(ToolChain.PATH.resolve("memlib.iloc"))); //$NON-NLS-1$ prog = Assembler.instance().assemble(memlib); + + String stdlib = new String(Files.readAllBytes(ToolChain.PATH.resolve("stdlib.iloc"))); //$NON-NLS-1$ + Program prog2 = Assembler.instance().assemble(stdlib); + try { + for (Instr instr : prog2.getInstr()) + prog.addInstr(instr); + } catch (Throwable t) { + t.printStackTrace(System.err); + } } catch (Exception e) { throw new RuntimeException(e); } @@ -823,88 +832,30 @@ public class BoppiGenerator extends BoppiBaseVisitor { @Override public Reg visitRead(ReadContext ctx) { - if (ctx.variable().size() > 1) { - for (VariableContext expr : ctx.variable()) { - visit(expr); + Reg res = null; + for (VariableContext expr : ctx.variable()) { + visit(expr); - if (SimpleType.BOOL.equals(an.types.get(expr)) || SimpleType.INT.equals(an.types.get(expr))) { - regPool.withReg((temp) -> { - emit("", OpCode.in, new Str(""), temp); //$NON-NLS-1$ //$NON-NLS-2$ - Reg addr = visit(expr); - emit("save to var " + expr.getText(), OpCode.store, temp, addr); //$NON-NLS-1$ - }); - } else if (SimpleType.CHAR.equals(an.types.get(expr))) { - // Get input until at least 1 character - Label getTarget = makeLabel("lcin_l"); //$NON-NLS-1$ - Label continueTarget = makeLabel("lcin_e"); //$NON-NLS-1$ - - regPool.withReg((temp, count) -> { - emit("", getTarget, OpCode.cin, new Str("")); //$NON-NLS-1$ //$NON-NLS-2$ - emit("str length", OpCode.pop, count); //$NON-NLS-1$ - emit("repeat if 0 length", OpCode.cbr, count, continueTarget, getTarget); //$NON-NLS-1$ - - // Get character - emit("pop whole string", continueTarget, OpCode.cpop, temp); //$NON-NLS-1$ - Reg addr = visit(expr); - emit("save to var " + expr.getText(), OpCode.cstore, temp, addr); //$NON-NLS-1$ - - // Pop all remaining characters - Label loopTarget = makeLabel("lcpop_l"); //$NON-NLS-1$ - Label iterTarget = makeLabel("lcpop_c"); //$NON-NLS-1$ - Label stopTarget = makeLabel("lcpop_e"); //$NON-NLS-1$ - emit("pop remaining", loopTarget, OpCode.subI, count, new Num(1), temp); //$NON-NLS-1$ - emit("pop remaining", OpCode.cbr, count, iterTarget, stopTarget); //$NON-NLS-1$ - emit("pop remaining", iterTarget, OpCode.cpop, temp); //$NON-NLS-1$ - emit("pop remaining", OpCode.jumpI, loopTarget); //$NON-NLS-1$ - emit("pop remaining", stopTarget, OpCode.nop); //$NON-NLS-1$ - }); - } else { - emit("reading unknown type", OpCode.haltI, new Num(0x72656164)); //$NON-NLS-1$ - } - } - - return null; - } else { - VariableContext expr = ctx.variable(0); - - if (SimpleType.BOOL.equals(an.types.get(expr)) || SimpleType.INT.equals(an.types.get(expr))) { - return regPool.withReg((result) -> { - emit("", OpCode.in, new Str(""), result); //$NON-NLS-1$ //$NON-NLS-2$ + if (SimpleType.BOOL.equals(an.types.get(expr)) || SimpleType.INT.equals(an.types.get(expr))) + res = regPool.withReg((temp) -> { + emit("", OpCode.in, new Str(""), temp); //$NON-NLS-1$ //$NON-NLS-2$ Reg addr = visit(expr); - emit("save to var " + expr.getText(), OpCode.store, result, addr); //$NON-NLS-1$ + emit("save to var " + expr.getText(), OpCode.store, temp, addr); //$NON-NLS-1$ }); - } else if (SimpleType.CHAR.equals(an.types.get(expr))) { - return regPool.withReg((count, result) -> { - // Get input until at least 1 character - Label getTarget = makeLabel("lcin_l"); //$NON-NLS-1$ - Label continueTarget = makeLabel("lcin_e"); //$NON-NLS-1$ - - emit("", getTarget, OpCode.cin, new Str("")); //$NON-NLS-1$ //$NON-NLS-2$ - emit("str length", OpCode.pop, count); //$NON-NLS-1$ - emit("repeat if 0 length", OpCode.cbr, count, continueTarget, getTarget); //$NON-NLS-1$ - - // Get character - emit("pop whole string", continueTarget, OpCode.cpop, result); //$NON-NLS-1$ + else if (SimpleType.CHAR.equals(an.types.get(expr))) + res = regPool.withReg((temp) -> { + emit("call stdcin", OpCode.loadI, new Num(prog.size() + 3), temp); //$NON-NLS-1$ + emit("call stdcin", OpCode.push, temp); //$NON-NLS-1$ + emit("call stdcin", OpCode.jumpI, new Label("stdcin")); //$NON-NLS-1$ //$NON-NLS-2$ + emit("get character", OpCode.cpop, temp); //$NON-NLS-1$ Reg addr = visit(expr); - emit("save to var " + expr.getText(), OpCode.cstore, result, addr); //$NON-NLS-1$ - - // Pop all remaining characters - Label loopTarget = makeLabel("lcpop_l"); //$NON-NLS-1$ - Label iterTarget = makeLabel("lcpop_c"); //$NON-NLS-1$ - Label stopTarget = makeLabel("lcpop_e"); //$NON-NLS-1$ - regPool.withReg((temp) -> { - emit("pop remaining", loopTarget, OpCode.subI, count, new Num(1), count); //$NON-NLS-1$ - emit("pop remaining", OpCode.cbr, count, iterTarget, stopTarget); //$NON-NLS-1$ - emit("pop remaining", iterTarget, OpCode.cpop, temp); //$NON-NLS-1$ - emit("pop remaining", OpCode.jumpI, loopTarget); //$NON-NLS-1$ - emit("pop remaining", stopTarget, OpCode.nop); //$NON-NLS-1$ - }); + emit("save to var " + expr.getText(), OpCode.cstore, temp, addr); //$NON-NLS-1$ }); - } else { + else emit("reading unknown type", OpCode.haltI, new Num(0x72656164)); //$NON-NLS-1$ - return null; - } } + + return res; } @Override @@ -1010,42 +961,21 @@ public class BoppiGenerator extends BoppiBaseVisitor { @Override public Reg visitWrite(WriteContext ctx) { - if (ctx.expr().size() > 1) { - for (ExprContext expr : ctx.expr()) { - Reg result = visit(expr); - - regPool.blockReg(result, () -> { - Type type = an.types.get(expr); - - if (SimpleType.BOOL.equals(type) || SimpleType.INT.equals(type)) { - emit("", OpCode.out, new Str(""), result); //$NON-NLS-1$ //$NON-NLS-2$ - } else if (SimpleType.CHAR.equals(type)) { - regPool.withReg((temp) -> { - emit("push character", OpCode.cpush, result); //$NON-NLS-1$ - emit("load 1", OpCode.loadI, new Num(1), temp); //$NON-NLS-1$ - emit("push 1", OpCode.push, temp); //$NON-NLS-1$ - emit("print character", OpCode.cout, new Str("")); //$NON-NLS-1$ //$NON-NLS-2$ - }); - } else { - emit("writing unknown type", OpCode.haltI, new Num(0x77726974)); //$NON-NLS-1$ - } - - if (!expr.equals(ctx.expr(ctx.expr().size() - 1))) - if (type instanceof ReferenceType) - decrementReference(type, result); - }); - } - return null; - } else { - ExprContext expr = ctx.expr(0); + for (ExprContext expr : ctx.expr()) { Reg result = visit(expr); - return regPool.blockReg(result, () -> { + regPool.blockReg(result, () -> { Type type = an.types.get(expr); - if (SimpleType.BOOL.equals(type) || SimpleType.INT.equals(type)) { + if (SimpleType.BOOL.equals(type)) { + regPool.withReg((temp) -> { + emit("call stdbout", OpCode.loadI, new Num(prog.size() + 4), temp); // $NON-NLS-2$ //$NON-NLS-1$ + emit("call stdbout", OpCode.push, temp); //$NON-NLS-1$ + emit("call stdbout", OpCode.push, result); //$NON-NLS-1$ + emit("call stdbout", OpCode.jumpI, new Label("stdbout")); //$NON-NLS-1$ //$NON-NLS-2$ + }); + } else if (SimpleType.INT.equals(type)) { emit("", OpCode.out, new Str(""), result); //$NON-NLS-1$ //$NON-NLS-2$ - return result; } else if (SimpleType.CHAR.equals(type)) { regPool.withReg((temp) -> { emit("push character", OpCode.cpush, result); //$NON-NLS-1$ @@ -1053,12 +983,19 @@ public class BoppiGenerator extends BoppiBaseVisitor { emit("push 1", OpCode.push, temp); //$NON-NLS-1$ emit("print character", OpCode.cout, new Str("")); //$NON-NLS-1$ //$NON-NLS-2$ }); - return result; } else { emit("writing unknown type", OpCode.haltI, new Num(0x77726974)); //$NON-NLS-1$ - return null; } + + if (!expr.equals(ctx.expr(ctx.expr().size() - 1))) + if (type instanceof ReferenceType) + decrementReference(type, result); }); + + if (ctx.expr().size() == 1) + return result; } + + return null; } } diff --git a/src/pp/s1184725/boppi/memlib.iloc b/src/pp/s1184725/boppi/memlib.iloc index 9e249b7..040fdfe 100644 --- a/src/pp/s1184725/boppi/memlib.iloc +++ b/src/pp/s1184725/boppi/memlib.iloc @@ -36,7 +36,7 @@ memlib_: loadI 0 => m_0 // allocate memory // searches through the free slots for either a slot size of ~~exactly #4+8 or a size of~~ at // least #4+16 -// memory: [return address, object size] -> [object address] +// stack: [return address, object size] -> [object address] memalloc: loadI 0 => m_0 pop => m_s // load size loadI @fst_ptr => m_p // load previous address (base pointer) @@ -77,7 +77,7 @@ ma_null: pop => m_1 // load return address // increase reference count of object -// memory: [return address, object address] -> [] +// stack: [return address, object address] -> [] memaddref: loadI 0 => m_0 pop => m_n // load object address cmp_EQ m_0,m_n => m_1 @@ -92,7 +92,7 @@ mr_nnul: loadAI m_n,@off_oref => m_1 // decrease reference count of object // frees memory if count goes to zero -// memory: [return address, object address] -> [] +// stack: [return address, object address] -> [] memfree: loadI 0 => m_0 pop => m_n // load object address cmp_EQ m_0,m_n => m_1 @@ -111,8 +111,8 @@ mf_free: subI m_n,@header => m_n loadI @fst_ptr => m_p loadAI m_p,@off_next => m_c -mf_loop: cmp_EQ m_0,m_c => m_1 // check if address pointer is null - cbr m_1 -> mf_halt,mf_cont +mf_loop: cmp_EQ m_0,m_c => m_1 // loop until the surrounding free blocks are found + cbr m_1 -> mf_halt,mf_cont // check if address pointer is null mf_halt: haltI 1882220141 // halt program; object beyond last free slot (or memory corrupted) mf_cont: cmp_EQ m_c,m_n => m_1 cbr m_1 -> mf_hal2,mf_con2 @@ -152,7 +152,7 @@ mf_nnxt: storeAI m_c => m_n,@off_next // link new free slot with next // copy object to location -// memory: [return address, object address, destination] -> [] +// stack: [return address, object address, destination] -> [] memcopy: loadI 0 => m_0 haltI 1835626101 // unimplemented pop => m_1 // load return address diff --git a/src/pp/s1184725/boppi/stdlib.iloc b/src/pp/s1184725/boppi/stdlib.iloc new file mode 100644 index 0000000..c347468 --- /dev/null +++ b/src/pp/s1184725/boppi/stdlib.iloc @@ -0,0 +1,39 @@ +// stdlib - generic subroutines for ILOC +// +// This library contains a few common subroutines for Boppi. +// +// @author Frank Wibbelink + +// initialise +stdlib_: jumpI -> estdlib_ + +// write a boolean to output +// stack: [return address, bool] -> [] +stdbout: pop => m_1 // get boolean + loadI 0 => m_2 // load zero-length string + push m_2 + cbr m_1 -> sbout_t,sbout_f +sbout_t: cout "true" + jumpI -> sbout_e +sbout_f: cout "false" +sbout_e: pop => m_1 // load return address + jump -> m_1 + + +// read a character from input +// stack: [return address] -> [char] +stdcin: cin "" // get line + pop => m_1 // get length + cbr m_1 -> scin_t,stdcin // repeat until at least one character +scin_t: cpop => m_2 // save character +scin_lc: subI m_1, 1 => m_1 // decrement char count + cbr m_1 -> scin_ll,scin_le +scin_ll: cpop => m_0 // discard character + jumpI -> scin_lc // repeat +scin_le: loadI 0 => m_0 // reset zero register + pop => m_1 // get return address + cpush m_2 // push result character + jump -> m_1 + +estdlib_: nop +// end of stdlib