Skip to content

Commit cbe3e86

Browse files
authored
Merge pull request #67 from fxnnhx/main
Munus implementation
2 parents a3d1db4 + 2f0c623 commit cbe3e86

12 files changed

Lines changed: 287 additions & 16 deletions

src/main/java/com/InterpreterMain.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ public static void main(String[] args) throws Exception {
2323
outStream.flush();
2424
}
2525

26-
}
26+
}

src/main/java/com/StmtParserMain.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,13 @@ public static void main(String[] args) throws Exception {
1212
DECLARE b;
1313
a = 1 + 2;
1414
b = 5;
15+
FUNCTION foo(c,d){
16+
RETURN 0;
17+
};
18+
c = 1;
19+
PRINT c;
1520
PRINT a ? b + 1 : -1;
16-
PRINT 1 + 2;
21+
PRINT CALL foo(a,b);
1722
PRINT 3 + 4;
1823
}
1924
""";

src/main/java/com/compiler/ExpressionParser.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,17 +227,18 @@ ASTExprNode getAndOrExpr() throws Exception {
227227
}
228228

229229
ASTExprNode getCallExpr() throws Exception {
230+
// callExpr: CALL IDENTIFIER LPAREN argList RPAREN
230231
if(m_lexer.m_currentToken.m_type != TokenIntf.Type.CALL) {
231232
return getParantheseExpr();
232233
}else {
233234
m_lexer.advance();
234235
String funcName = m_lexer.m_currentToken.m_value;
236+
m_lexer.expect(TokenIntf.Type.IDENT);
235237
FunctionInfo functionInfo = m_functionTable.getFunction(funcName);
236238
if(functionInfo == null) {
237239
m_lexer.throwCompilerException(String.format("%s not declared" , funcName), "");
238240
}
239241

240-
m_lexer.expect(TokenIntf.Type.IDENT);
241242
m_lexer.expect(TokenIntf.Type.LPAREN);
242243
List<ASTExprNode> argumentList = getArgumentList();
243244
if(argumentList.size() != functionInfo.varNames.size()){
@@ -251,8 +252,9 @@ ASTExprNode getCallExpr() throws Exception {
251252
}
252253

253254
private List<ASTExprNode> getArgumentList() throws Exception {
255+
// argList: expr argListPost | eps
256+
// argListPost: eps | COMMA expr argListPost
254257
List<ASTExprNode> argumentList = new ArrayList<>();
255-
256258
if(m_lexer.m_currentToken.m_type == Type.RPAREN){
257259
return argumentList;
258260
}else {

src/main/java/com/compiler/StmtParser.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,39 +92,52 @@ public ASTStmtNode parseStmt() throws Exception {
9292
}
9393

9494
public ASTStmtNode parseFunctionStmt() throws Exception {
95+
// functionDecl: FUNCTION IDENTIFIER RPAREN paramList RPAREN LBRACE functionBody RBRACE SEMICOLON
9596
m_lexer.expect(Type.FUNCTION);
9697
String functionName = m_lexer.m_currentToken.m_value;
98+
9799
m_lexer.expect(TokenIntf.Type.IDENT);
98100
m_lexer.expect(Type.LPAREN);
101+
99102
List<String> parameterList = parseParameterList();
100-
parameterList.forEach(e -> m_symbolTable.createSymbol(e));
101-
m_lexer.expect(TokenIntf.Type.RPAREN);
103+
parameterList.forEach(m_symbolTable::createSymbol);
104+
m_functionTable.createFunction(functionName, parameterList);
102105

106+
m_lexer.expect(TokenIntf.Type.RPAREN);
103107
m_lexer.expect(TokenIntf.Type.LBRACE);
108+
104109
List<ASTStmtNode> functionBody = parseFunctionBody();
110+
105111
m_lexer.expect(TokenIntf.Type.RBRACE);
106112
m_lexer.expect(Type.SEMICOLON);
107-
m_functionTable.createFunction(functionName, parameterList);
113+
108114
return new ASTFunctionStmtNode(functionName, parameterList, functionBody);
109115
}
110116

111117
private List<ASTStmtNode> parseFunctionBody() throws Exception {
118+
// functionBody: returnStmt | stmt functionBody
112119
List<ASTStmtNode> stmtList = new ArrayList<>();
113120
while(m_lexer.m_currentToken.m_type != Type.RETURN){
121+
if(m_lexer.m_currentToken.m_type == Type.RBRACE){
122+
m_lexer.throwCompilerException("Invalid end of function body", "RETURN");
123+
}
114124
stmtList.add(parseStmt());
115125
}
116126
stmtList.add(parseReturnStmt());
117127
return stmtList;
118128
}
119129

120130
private ASTStmtNode parseReturnStmt() throws Exception {
131+
// returnStmt: RETURN expr
121132
m_lexer.expect(Type.RETURN);
122133
ASTStmtNode returnStmtNode = new ASTReturnStmtNode(m_exprParser.getQuestionMarkExpr());
123134
m_lexer.expect(Type.SEMICOLON);
124135
return returnStmtNode;
125136
}
126137

127138
private List<String> parseParameterList() throws Exception {
139+
// paramList: IDENTIFIER paramListPos | eps
140+
// paramListPost: eps | COMMA IDENFIER paramListPost
128141
List<String> parameterList = new ArrayList<>();
129142
if(m_lexer.m_currentToken.m_type != Type.IDENT){
130143
return parameterList;
@@ -143,7 +156,6 @@ private List<String> parseParameterList() throws Exception {
143156

144157
public ASTStmtNode parsePrintStmt() throws Exception {
145158
m_lexer.expect(Type.PRINT);
146-
147159
ASTPrintStmtNode astPrintStmtNode = new ASTPrintStmtNode(m_exprParser.getQuestionMarkExpr());
148160
m_lexer.expect(Type.SEMICOLON);
149161
return astPrintStmtNode;

src/main/java/com/compiler/ast/ASTCallExprNode.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
package com.compiler.ast;
22

3+
import com.compiler.InstrBlock;
4+
import com.compiler.InstrIntf;
5+
import com.compiler.instr.InstrJump;
6+
import com.compiler.instr.InstrPopValueStack;
7+
import com.compiler.instr.InstrPushCallStack;
8+
import com.compiler.instr.InstrPushValueStack;
9+
310
import java.io.OutputStreamWriter;
411
import java.util.List;
512

@@ -14,11 +21,33 @@ public ASTCallExprNode(String funcName, List<ASTExprNode> argumentList) {
1421

1522
@Override
1623
public int eval() {
17-
return 0;
24+
return 0; // not implemented, as Call Expression only returns a value with prior function stmt
1825
}
1926

2027
@Override
2128
public void print(OutputStreamWriter outStream, String indent) throws Exception {
29+
outStream.write(indent);
30+
outStream.write("ASTCallExpressionNode ");
31+
outStream.write("\n");
32+
for (ASTExprNode astExprNode : m_argumentList) {
33+
astExprNode.print(outStream, indent + " ");
34+
}
35+
}
36+
37+
@Override
38+
public InstrIntf codegen(com.compiler.CompileEnvIntf env) {
39+
m_argumentList.stream()
40+
.map(arg -> arg.codegen(env))
41+
.forEach(argInstr -> env.addInstr(new InstrPushValueStack(argInstr)));
2242

43+
env.addInstr(new InstrPushCallStack());
44+
45+
InstrBlock functionBodyBlock = env.getFunctionTable().getFunction(m_funcName).m_body;
46+
env.addInstr(new InstrJump(functionBodyBlock));
47+
48+
InstrIntf popInstr = new InstrPopValueStack();
49+
env.addInstr(popInstr);
50+
return popInstr;
2351
}
52+
2453
}

src/main/java/com/compiler/ast/ASTFunctionStmtNode.java

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package com.compiler.ast;
22

33
import java.io.OutputStreamWriter;
4+
import java.util.Collections;
45
import java.util.List;
56

67
import com.compiler.CompileEnvIntf;
7-
import com.compiler.FunctionInfo;
8-
import com.compiler.FunctionTable;
98
import com.compiler.InstrBlock;
9+
import com.compiler.instr.InstrAssign;
10+
import com.compiler.instr.InstrPopValueStack;
1011

1112
public class ASTFunctionStmtNode extends ASTStmtNode {
1213
String m_functionName;
@@ -22,14 +23,40 @@ public ASTFunctionStmtNode(String functionName, List<String> parameterList, List
2223

2324
@Override
2425
public void execute(OutputStreamWriter out) {
25-
26+
// nothing to do at runtime
2627
}
2728

2829
@Override
2930
public void codegen(CompileEnvIntf env) {
30-
super.codegen(env);
31+
InstrBlock codegenEntryBlock = env.getCurrentBlock();
32+
33+
InstrBlock functionBodyBlock = env.createBlock("function_"+m_functionName);
34+
env.setCurrentBlock(functionBodyBlock);
35+
36+
m_parameterList.stream()
37+
.sorted(Collections.reverseOrder())
38+
.map(env.getSymbolTable()::getSymbol)
39+
.forEach(parameter -> {
40+
InstrPopValueStack popStackInstr = new InstrPopValueStack();
41+
env.addInstr(popStackInstr);
42+
InstrAssign assignInstr = new InstrAssign(parameter, popStackInstr);
43+
env.addInstr(assignInstr);
44+
});
45+
46+
m_functionBody.forEach(stmt -> stmt.codegen(env));
47+
48+
env.getFunctionTable().getFunction(m_functionName).m_body = functionBodyBlock;
49+
50+
env.setCurrentBlock(codegenEntryBlock);
3151
}
3252

3353
@Override
34-
public void print(OutputStreamWriter outStream, String indent) throws Exception {}
54+
public void print(OutputStreamWriter outStream, String indent) throws Exception {
55+
outStream.write(indent);
56+
outStream.write("ASTFunctionStmtNode ");
57+
outStream.write("\n");
58+
for (ASTStmtNode astStmtNode : m_functionBody) {
59+
astStmtNode.print(outStream, indent + " ");
60+
}
61+
}
3562
}

src/main/java/com/compiler/ast/ASTReturnStmtNode.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package com.compiler.ast;
22

3+
import com.compiler.CompileEnvIntf;
4+
import com.compiler.instr.InstrPushValueStack;
5+
import com.compiler.instr.InstrReturn;
6+
37
import java.io.OutputStreamWriter;
48

59
public class ASTReturnStmtNode extends ASTStmtNode {
@@ -11,11 +15,19 @@ public ASTReturnStmtNode(ASTExprNode questionMarkExpr) {
1115

1216
@Override
1317
public void execute(OutputStreamWriter out) {
14-
18+
// nothing to do
1519
}
1620

1721
@Override
1822
public void print(OutputStreamWriter outStream, String indent) throws Exception {
19-
23+
outStream.write(indent);
24+
outStream.write("ASTReturnStmtNode ");
25+
outStream.write("\n");
26+
m_expr.print(outStream, indent + " ");
27+
}
28+
@Override
29+
public void codegen(CompileEnvIntf env) {
30+
env.addInstr(new InstrPushValueStack(m_expr.codegen(env)));
31+
env.addInstr(new InstrReturn());
2032
}
2133
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.compiler.instr;
2+
3+
import com.compiler.ExecutionEnvIntf;
4+
import com.compiler.InstrIntf;
5+
6+
import java.io.OutputStreamWriter;
7+
8+
public class InstrPopValueStack extends InstrIntf {
9+
10+
public InstrPopValueStack() {}
11+
12+
@Override
13+
public void execute(ExecutionEnvIntf env) throws Exception {
14+
m_value = env.pop();
15+
}
16+
17+
@Override
18+
public void trace(OutputStreamWriter os) throws Exception {
19+
os.write(String.format("%%%d = POP\n",
20+
m_id
21+
));
22+
}
23+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.compiler.instr;
2+
3+
import com.compiler.ExecutionEnvIntf;
4+
import com.compiler.InstrIntf;
5+
6+
import java.io.OutputStreamWriter;
7+
8+
public class InstrPushCallStack extends InstrIntf {
9+
@Override
10+
public void execute(ExecutionEnvIntf env) throws Exception {
11+
env.pushReturnAddr(env.getInstrIter());
12+
}
13+
14+
@Override
15+
public void trace(OutputStreamWriter os) throws Exception {
16+
os.write("PUSH_RETURN_ADDR\n");
17+
18+
}
19+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.compiler.instr;
2+
3+
import com.compiler.ExecutionEnvIntf;
4+
import com.compiler.InstrIntf;
5+
6+
import java.io.OutputStreamWriter;
7+
8+
public class InstrPushValueStack extends InstrIntf {
9+
InstrIntf m_instruction;
10+
public InstrPushValueStack(InstrIntf instruction) {
11+
m_instruction = instruction;
12+
}
13+
14+
@Override
15+
public void execute(ExecutionEnvIntf env) throws Exception {
16+
env.push(m_instruction.getValue());
17+
}
18+
19+
@Override
20+
public void trace(OutputStreamWriter os) throws Exception {
21+
os.write(String.format("PUSH %%%d\n",
22+
m_instruction.getId()
23+
));
24+
}
25+
}

0 commit comments

Comments
 (0)