diff --git a/src/main/antlr/MellowDParser.g4 b/src/main/antlr/MellowDParser.g4 index 05cd18a..dbd9819 100644 --- a/src/main/antlr/MellowDParser.g4 +++ b/src/main/antlr/MellowDParser.g4 @@ -190,7 +190,7 @@ value //Each mapping is put into the compiler's symbol table. Adding a `*` after the assignment token //parses the value as if it was inside a percussion block. varDeclaration - : IDENTIFIER ASSIGNMENT STAR? value + : identifier ASSIGNMENT STAR? value ; //Dynamics are what change the velocity of a note. Mellow D supports the main dynamic identifiers diff --git a/src/main/java/cas/cs4tb3/mellowd/intermediate/RepeatedPhrase.java b/src/main/java/cas/cs4tb3/mellowd/intermediate/RepeatedPhrase.java deleted file mode 100644 index 4ce2ff6..0000000 --- a/src/main/java/cas/cs4tb3/mellowd/intermediate/RepeatedPhrase.java +++ /dev/null @@ -1,36 +0,0 @@ -package cas.cs4tb3.mellowd.intermediate; - -import cas.cs4tb3.mellowd.midi.TimingEnvironment; -import cas.cs4tb3.mellowd.midi.MIDIChannel; -import cas.cs4tb3.mellowd.primitives.Beat; -import cas.cs4tb3.mellowd.primitives.Melody; -import cas.cs4tb3.mellowd.primitives.Rhythm; - -public class RepeatedPhrase extends Phrase { - protected final int repetitions; - - public RepeatedPhrase(Melody melody, Rhythm rhythm, int repetitions) { - super(melody, rhythm); - this.repetitions = repetitions; - } - - public int getRepetitions() { - return repetitions; - } - - @Override - public Beat getDuration() { - return new Beat(super.getDuration().getNumQuarters() * repetitions); - } - - @Override - public void play(MIDIChannel channel) { - for (int i = 0; i < repetitions; i++) - super.play(channel); - } - - @Override - public long calculateDuration(TimingEnvironment env) { - return super.calculateDuration(env) * repetitions; - } -} diff --git a/src/main/java/cas/cs4tb3/mellowd/intermediate/executable/statements/RepeatedCodeBlock.java b/src/main/java/cas/cs4tb3/mellowd/intermediate/executable/statements/RepeatedCodeBlock.java index f0c35bc..a031664 100644 --- a/src/main/java/cas/cs4tb3/mellowd/intermediate/executable/statements/RepeatedCodeBlock.java +++ b/src/main/java/cas/cs4tb3/mellowd/intermediate/executable/statements/RepeatedCodeBlock.java @@ -2,9 +2,12 @@ import cas.cs4tb3.mellowd.intermediate.Output; import cas.cs4tb3.mellowd.intermediate.executable.expressions.Expression; +import cas.cs4tb3.mellowd.intermediate.variables.Memory; import cas.cs4tb3.mellowd.parser.ExecutionEnvironment; public class RepeatedCodeBlock extends CodeBlock { + public static final String IMPLICIT_LOOP_COUNTER_ID = "it"; + protected final Expression repetitions; public RepeatedCodeBlock(Expression repetitions) { @@ -15,10 +18,16 @@ public RepeatedCodeBlock(Expression repetitions) { @Override public void execute(ExecutionEnvironment environment, Output output) { int repetitions = this.repetitions.evaluate(environment).intValue(); + Memory memory = environment.getMemory(); + Object old = memory.get(IMPLICIT_LOOP_COUNTER_ID); + for (int i = 0; i < repetitions; i++) { + memory.set(IMPLICIT_LOOP_COUNTER_ID, i); for (Statement stmt : super.statements) { stmt.execute(environment, output); } } + + memory.set(IMPLICIT_LOOP_COUNTER_ID, old); } } diff --git a/src/main/java/cas/cs4tb3/mellowd/parser/MellowDCompiler.java b/src/main/java/cas/cs4tb3/mellowd/parser/MellowDCompiler.java index 8a2397b..df53954 100644 --- a/src/main/java/cas/cs4tb3/mellowd/parser/MellowDCompiler.java +++ b/src/main/java/cas/cs4tb3/mellowd/parser/MellowDCompiler.java @@ -111,7 +111,7 @@ public Integer visitNumber(MellowDParser.NumberContext ctx) { @Override public Expression visitNumberOrId(MellowDParser.NumberOrIdContext ctx) { MellowDParser.IdentifierContext idCtx = ctx.identifier(); - if (idCtx != null) return lookupIdentifier(idCtx, Integer.class); + if (idCtx != null) return new RuntimeNullCheck<>(idCtx.getText(), lookupIdentifier(idCtx, Integer.class), idCtx); return new Constant<>(visitNumber(ctx.number())); } @@ -416,9 +416,11 @@ public Expression visitValue(MellowDParser.ValueContext ctx) { public Statement visitVarDeclaration(MellowDParser.VarDeclarationContext ctx, boolean isField) { boolean percussionToggle = ctx.STAR() != null; + Identifier identifier = visitIdentifier(ctx.identifier()); + Expression valueExpr = visitValue(ctx.value()); - return new AssignmentStatement(new String[0], ctx.IDENTIFIER().getText(), valueExpr, isField, percussionToggle); + return new AssignmentStatement(identifier.qualifier, identifier.name, valueExpr, isField, percussionToggle); } @Override