From bf7fc349d7aeba9ed84db7cd6a9a431c03a21b81 Mon Sep 17 00:00:00 2001 From: Stefan Marr Date: Tue, 17 Mar 2020 17:28:18 +0000 Subject: [PATCH] Refactor Parser to be less mutable - move ClassGenerationContext into it - make MethodGenerationContext more immutable by preferring constructor over setters - let assemble do the right thing without external check of flag Signed-off-by: Stefan Marr --- src/som/compiler/ClassGenerationContext.java | 4 +- src/som/compiler/MethodGenerationContext.java | 46 ++++++++++++----- src/som/compiler/Parser.java | 50 ++++++++----------- src/som/compiler/SourcecodeCompiler.java | 3 +- 4 files changed, 57 insertions(+), 46 deletions(-) diff --git a/src/som/compiler/ClassGenerationContext.java b/src/som/compiler/ClassGenerationContext.java index 8a4a64f..62ae2e8 100644 --- a/src/som/compiler/ClassGenerationContext.java +++ b/src/som/compiler/ClassGenerationContext.java @@ -75,8 +75,8 @@ public void addInstanceMethod(final som.vmobjects.SInvokable meth) { instanceMethods.add(meth); } - public void setClassSide(boolean b) { - classSide = b; + public void startClassSide() { + classSide = true; } public void addClassMethod(final som.vmobjects.SInvokable meth) { diff --git a/src/som/compiler/MethodGenerationContext.java b/src/som/compiler/MethodGenerationContext.java index 591a5b9..d04cb21 100644 --- a/src/som/compiler/MethodGenerationContext.java +++ b/src/som/compiler/MethodGenerationContext.java @@ -25,7 +25,22 @@ package som.compiler; -import static som.interpreter.Bytecodes.*; +import static som.interpreter.Bytecodes.DUP; +import static som.interpreter.Bytecodes.HALT; +import static som.interpreter.Bytecodes.POP; +import static som.interpreter.Bytecodes.POP_ARGUMENT; +import static som.interpreter.Bytecodes.POP_FIELD; +import static som.interpreter.Bytecodes.POP_LOCAL; +import static som.interpreter.Bytecodes.PUSH_ARGUMENT; +import static som.interpreter.Bytecodes.PUSH_BLOCK; +import static som.interpreter.Bytecodes.PUSH_CONSTANT; +import static som.interpreter.Bytecodes.PUSH_FIELD; +import static som.interpreter.Bytecodes.PUSH_GLOBAL; +import static som.interpreter.Bytecodes.PUSH_LOCAL; +import static som.interpreter.Bytecodes.RETURN_LOCAL; +import static som.interpreter.Bytecodes.RETURN_NON_LOCAL; +import static som.interpreter.Bytecodes.SEND; +import static som.interpreter.Bytecodes.SUPER_SEND; import java.util.ArrayList; import java.util.List; @@ -41,8 +56,9 @@ public class MethodGenerationContext { - private ClassGenerationContext holderGenc; - private MethodGenerationContext outerGenc; + private final ClassGenerationContext holderGenc; + private final MethodGenerationContext outerGenc; + private boolean blockMethod; private SSymbol signature; private final List arguments = new ArrayList(); @@ -52,8 +68,14 @@ public class MethodGenerationContext { private boolean finished; private final Vector bytecode = new Vector(); - public void setHolder(final ClassGenerationContext cgenc) { - holderGenc = cgenc; + public MethodGenerationContext(final ClassGenerationContext holderGenc, + final MethodGenerationContext outerGenc) { + this.holderGenc = holderGenc; + this.outerGenc = outerGenc; + } + + public MethodGenerationContext(final ClassGenerationContext holderGenc) { + this(holderGenc, null); } public void addArgument(final String arg) { @@ -64,11 +86,15 @@ public boolean isPrimitive() { return primitive; } - public SInvokable assemblePrimitive(final Universe universe) { - return SPrimitive.getEmptyPrimitive(signature.getEmbeddedString(), universe); + public SInvokable assemble(final Universe universe) { + if (primitive) { + return SPrimitive.getEmptyPrimitive(signature.getEmbeddedString(), universe); + } else { + return assembleMethod(universe); + } } - public SMethod assemble(final Universe universe) { + public SMethod assembleMethod(final Universe universe) { // create a method instance with the given number of bytecodes and // literals int numLiterals = literals.size(); @@ -223,10 +249,6 @@ public ClassGenerationContext getHolder() { return holderGenc; } - public void setOuter(final MethodGenerationContext mgenc) { - outerGenc = mgenc; - } - public byte addLiteral(final SAbstractObject lit) { int i = literals.size(); assert i < 128; diff --git a/src/som/compiler/Parser.java b/src/som/compiler/Parser.java index d276081..a24ad72 100644 --- a/src/som/compiler/Parser.java +++ b/src/som/compiler/Parser.java @@ -75,8 +75,9 @@ public class Parser { - private final Universe universe; - private final String filename; + private final Universe universe; + private final String filename; + private final ClassGenerationContext cgenc; private final Lexer lexer; private final BytecodeGenerator bcGen; @@ -178,6 +179,7 @@ public String toString() { public Parser(final Reader reader, final Universe universe, final String filename) { this.universe = universe; this.filename = filename; + this.cgenc = new ClassGenerationContext(universe); sym = NONE; lexer = new Lexer(reader); @@ -186,52 +188,42 @@ public Parser(final Reader reader, final Universe universe, final String filenam getSymbolFromLexer(); } - public void classdef(final ClassGenerationContext cgenc) throws ProgramDefinitionError { + public ClassGenerationContext classdef() throws ProgramDefinitionError { cgenc.setName(universe.symbolFor(text)); expect(Identifier); expect(Equal); - superclass(cgenc); + superclass(); expect(NewTerm); - instanceFields(cgenc); + instanceFields(); while (sym == Identifier || sym == Keyword || sym == OperatorSequence || symIn(binaryOpSyms)) { - MethodGenerationContext mgenc = new MethodGenerationContext(); - mgenc.setHolder(cgenc); + MethodGenerationContext mgenc = new MethodGenerationContext(cgenc); mgenc.addArgument("self"); method(mgenc); - - if (mgenc.isPrimitive()) { - cgenc.addInstanceMethod(mgenc.assemblePrimitive(universe)); - } else { - cgenc.addInstanceMethod(mgenc.assemble(universe)); - } + cgenc.addInstanceMethod(mgenc.assemble(universe)); } if (accept(Separator)) { - cgenc.setClassSide(true); - classFields(cgenc); + cgenc.startClassSide(); + classFields(); while (sym == Identifier || sym == Keyword || sym == OperatorSequence || symIn(binaryOpSyms)) { - MethodGenerationContext mgenc = new MethodGenerationContext(); - mgenc.setHolder(cgenc); + MethodGenerationContext mgenc = new MethodGenerationContext(cgenc); mgenc.addArgument("self"); method(mgenc); - - if (mgenc.isPrimitive()) { - cgenc.addClassMethod(mgenc.assemblePrimitive(universe)); - } else { - cgenc.addClassMethod(mgenc.assemble(universe)); - } + cgenc.addClassMethod(mgenc.assemble(universe)); } } expect(EndTerm); + + return cgenc; } - private void superclass(final ClassGenerationContext cgenc) throws ProgramDefinitionError { + private void superclass() throws ProgramDefinitionError { SSymbol superName; if (sym == Identifier) { superName = universe.symbolFor(text); @@ -306,7 +298,7 @@ private boolean expectOneOf(final List ss) { throw new IllegalStateException(err.toString()); } - private void instanceFields(final ClassGenerationContext cgenc) { + private void instanceFields() { if (accept(Or)) { while (sym == Identifier) { String var = variable(); @@ -316,7 +308,7 @@ private void instanceFields(final ClassGenerationContext cgenc) { } } - private void classFields(final ClassGenerationContext cgenc) { + private void classFields() { if (accept(Or)) { while (sym == Identifier) { String var = variable(); @@ -564,14 +556,12 @@ private void primary(final MethodGenerationContext mgenc, final Single nestedTerm(mgenc); break; case NewBlock: { - MethodGenerationContext bgenc = new MethodGenerationContext(); + MethodGenerationContext bgenc = new MethodGenerationContext(mgenc.getHolder(), mgenc); bgenc.setIsBlockMethod(true); - bgenc.setHolder(mgenc.getHolder()); - bgenc.setOuter(mgenc); nestedBlock(bgenc); - SMethod blockMethod = bgenc.assemble(universe); + SMethod blockMethod = bgenc.assembleMethod(universe); mgenc.addLiteral(blockMethod); bcGen.emitPUSHBLOCK(mgenc, blockMethod); break; diff --git a/src/som/compiler/SourcecodeCompiler.java b/src/som/compiler/SourcecodeCompiler.java index 5a59913..3fc54be 100644 --- a/src/som/compiler/SourcecodeCompiler.java +++ b/src/som/compiler/SourcecodeCompiler.java @@ -79,10 +79,9 @@ private som.vmobjects.SClass compileClassString(final String stream, private som.vmobjects.SClass compile(final som.vmobjects.SClass systemClass, final Universe universe) throws ProgramDefinitionError { - ClassGenerationContext cgc = new ClassGenerationContext(universe); som.vmobjects.SClass result = systemClass; - parser.classdef(cgc); + ClassGenerationContext cgc = parser.classdef(); if (systemClass == null) { result = cgc.assemble();