From 6a7ac2a6f83fef42ebf8808a3f7d2a128747ab0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C5=A1per=20Dobrovoljc?= Date: Wed, 4 Jun 2025 14:19:59 +0200 Subject: [PATCH] Predrok 2025 - Naloga 2 --- .gitignore | 1 - grammar.txt | 26 +++++++++++- prg/test.pins25 | 13 ++++++ src/pins25/phase/CodeGen.java | 76 ++++++++++++++++++++++++++--------- 4 files changed, 96 insertions(+), 20 deletions(-) create mode 100644 prg/test.pins25 diff --git a/.gitignore b/.gitignore index 585d773..5545717 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,3 @@ out/ *.zip prg/**/*.ast prg/**/*.out -prg/**/*.pins25 \ No newline at end of file diff --git a/grammar.txt b/grammar.txt index 4de9353..e696064 100644 --- a/grammar.txt +++ b/grammar.txt @@ -69,4 +69,28 @@ restinits -> COMMA initializer restinits | . initializer -> INTCONST intconstmult | CHARCONST | STRINGCONST . intconstmult -> MUL const | . -const -> INTCONST | CHARCONST | STRINGCONST . \ No newline at end of file +const -> INTCONST | CHARCONST | STRINGCONST . + + +-------------------------------------------------------------------- + +//LEFT ASOC. +exp0 = exp0 op other | other + + | + v + +exp0 = other exp0' +exp0' = op other exp0' | . + + + + +//RIGHT ASOC. +exp0 = other op exp0 | other + + | + v + +exp0 = other exp0' +exp0' = op exp0 | . \ No newline at end of file diff --git a/prg/test.pins25 b/prg/test.pins25 new file mode 100644 index 0000000..c00669b --- /dev/null +++ b/prg/test.pins25 @@ -0,0 +1,13 @@ +fun putstr(n) +fun putint(b) + +fun a() = putstr("a called\n\00"), 40 +fun b() = putstr("b called\n\00"), 7 + +fun main() = + putint(10 % 7), + putstr("\n\00"), + putint(30 % 25), + putstr("\n\00"), + putint(a() % b()), + putstr("\n\00") \ No newline at end of file diff --git a/src/pins25/phase/CodeGen.java b/src/pins25/phase/CodeGen.java index 0df12ac..a9cc08f 100644 --- a/src/pins25/phase/CodeGen.java +++ b/src/pins25/phase/CodeGen.java @@ -231,26 +231,60 @@ public class CodeGen { List code = new ArrayList<>(); - code.addAll(binExpr.fstExpr.accept(this, frame)); - code.addAll(binExpr.sndExpr.accept(this, frame)); + if (binExpr.oper == AST.BinExpr.Oper.MOD) { + // a - a / b * b - PDM.OPER.Oper oper = switch (binExpr.oper) { - case OR -> PDM.OPER.Oper.OR; - case AND -> PDM.OPER.Oper.AND; - case EQU -> PDM.OPER.Oper.EQU; - case NEQ -> PDM.OPER.Oper.NEQ; - case GTH -> PDM.OPER.Oper.GTH; - case LTH -> PDM.OPER.Oper.LTH; - case GEQ -> PDM.OPER.Oper.GEQ; - case LEQ -> PDM.OPER.Oper.LEQ; - case ADD -> PDM.OPER.Oper.ADD; - case SUB -> PDM.OPER.Oper.SUB; - case MUL -> PDM.OPER.Oper.MUL; - case DIV -> PDM.OPER.Oper.DIV; - case MOD -> PDM.OPER.Oper.MOD; - }; + String tmpLabel = "$tmp@" + loc.location().begLine() + ":" + loc.location().begColumn(); - code.add(new PDM.OPER(oper, loc)); + code.addAll(binExpr.fstExpr.accept(this, frame)); + // dup a + code.add(new PDM.REGN(PDM.REGN.Reg.SP, loc)); + code.add(new PDM.LOAD(loc)); + + code.addAll(binExpr.sndExpr.accept(this, frame)); + // dup b + code.add(new PDM.REGN(PDM.REGN.Reg.SP, loc)); + code.add(new PDM.LOAD(loc)); + // save b + code.add(new PDM.NAME(tmpLabel, loc)); + code.add(new PDM.SAVE(loc)); + + code.add(new PDM.OPER(PDM.OPER.Oper.DIV, loc)); + + // load second b + code.add(new PDM.NAME(tmpLabel, loc)); + code.add(new PDM.LOAD(loc)); + + code.add(new PDM.OPER(PDM.OPER.Oper.MUL, loc)); + + code.add(new PDM.OPER(PDM.OPER.Oper.SUB, loc)); + + List data = new ArrayList<>(); + data.add(new PDM.LABEL(tmpLabel, loc)); + data.add(new PDM.DATA(0, loc)); + attrAST.attrData.put(binExpr, data); + } else { + code.addAll(binExpr.fstExpr.accept(this, frame)); + code.addAll(binExpr.sndExpr.accept(this, frame)); + + PDM.OPER.Oper oper = switch (binExpr.oper) { + case OR -> PDM.OPER.Oper.OR; + case AND -> PDM.OPER.Oper.AND; + case EQU -> PDM.OPER.Oper.EQU; + case NEQ -> PDM.OPER.Oper.NEQ; + case GTH -> PDM.OPER.Oper.GTH; + case LTH -> PDM.OPER.Oper.LTH; + case GEQ -> PDM.OPER.Oper.GEQ; + case LEQ -> PDM.OPER.Oper.LEQ; + case ADD -> PDM.OPER.Oper.ADD; + case SUB -> PDM.OPER.Oper.SUB; + case MUL -> PDM.OPER.Oper.MUL; + case DIV -> PDM.OPER.Oper.DIV; + case MOD -> PDM.OPER.Oper.MOD; + }; + + code.add(new PDM.OPER(oper, loc)); + } attrAST.attrCode.put(binExpr, code); return code; @@ -683,6 +717,12 @@ public class CodeGen { return null; } + @Override + public Object visit(AST.BinExpr binExpr, Object arg) { + List data = attrAST.attrData.get(binExpr); + if (data != null) dataSegment.addAll(data); + return null; + } } }