Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/java/com/InterpreterMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ public static void main(String[] args) throws Exception {
outStream.flush();
}

}
}
7 changes: 6 additions & 1 deletion src/main/java/com/StmtParserMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ public static void main(String[] args) throws Exception {
DECLARE b;
a = 1 + 2;
b = 5;
FUNCTION foo(c,d){
RETURN 0;
};
c = 1;
PRINT c;
PRINT a ? b + 1 : -1;
PRINT 1 + 2;
PRINT CALL foo(a,b);
PRINT 3 + 4;
}
""";
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/com/compiler/ExpressionParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -227,17 +227,18 @@ ASTExprNode getAndOrExpr() throws Exception {
}

ASTExprNode getCallExpr() throws Exception {
// callExpr: CALL IDENTIFIER LPAREN argList RPAREN
if(m_lexer.m_currentToken.m_type != TokenIntf.Type.CALL) {
return getParantheseExpr();
}else {
m_lexer.advance();
String funcName = m_lexer.m_currentToken.m_value;
m_lexer.expect(TokenIntf.Type.IDENT);
FunctionInfo functionInfo = m_functionTable.getFunction(funcName);
if(functionInfo == null) {
m_lexer.throwCompilerException(String.format("%s not declared" , funcName), "");
}

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

private List<ASTExprNode> getArgumentList() throws Exception {
// argList: expr argListPost | eps
// argListPost: eps | COMMA expr argListPost
List<ASTExprNode> argumentList = new ArrayList<>();

if(m_lexer.m_currentToken.m_type == Type.RPAREN){
return argumentList;
}else {
Expand Down
20 changes: 16 additions & 4 deletions src/main/java/com/compiler/StmtParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,39 +92,52 @@ public ASTStmtNode parseStmt() throws Exception {
}

public ASTStmtNode parseFunctionStmt() throws Exception {
// functionDecl: FUNCTION IDENTIFIER RPAREN paramList RPAREN LBRACE functionBody RBRACE SEMICOLON
m_lexer.expect(Type.FUNCTION);
String functionName = m_lexer.m_currentToken.m_value;

m_lexer.expect(TokenIntf.Type.IDENT);
m_lexer.expect(Type.LPAREN);

List<String> parameterList = parseParameterList();
parameterList.forEach(e -> m_symbolTable.createSymbol(e));
m_lexer.expect(TokenIntf.Type.RPAREN);
parameterList.forEach(m_symbolTable::createSymbol);
m_functionTable.createFunction(functionName, parameterList);

m_lexer.expect(TokenIntf.Type.RPAREN);
m_lexer.expect(TokenIntf.Type.LBRACE);

List<ASTStmtNode> functionBody = parseFunctionBody();

m_lexer.expect(TokenIntf.Type.RBRACE);
m_lexer.expect(Type.SEMICOLON);
m_functionTable.createFunction(functionName, parameterList);

return new ASTFunctionStmtNode(functionName, parameterList, functionBody);
}

private List<ASTStmtNode> parseFunctionBody() throws Exception {
// functionBody: returnStmt | stmt functionBody
List<ASTStmtNode> stmtList = new ArrayList<>();
while(m_lexer.m_currentToken.m_type != Type.RETURN){
if(m_lexer.m_currentToken.m_type == Type.RBRACE){
m_lexer.throwCompilerException("Invalid end of function body", "RETURN");
}
stmtList.add(parseStmt());
}
stmtList.add(parseReturnStmt());
return stmtList;
}

private ASTStmtNode parseReturnStmt() throws Exception {
// returnStmt: RETURN expr
m_lexer.expect(Type.RETURN);
ASTStmtNode returnStmtNode = new ASTReturnStmtNode(m_exprParser.getQuestionMarkExpr());
m_lexer.expect(Type.SEMICOLON);
return returnStmtNode;
}

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

public ASTStmtNode parsePrintStmt() throws Exception {
m_lexer.expect(Type.PRINT);

ASTPrintStmtNode astPrintStmtNode = new ASTPrintStmtNode(m_exprParser.getQuestionMarkExpr());
m_lexer.expect(Type.SEMICOLON);
return astPrintStmtNode;
Expand Down
31 changes: 30 additions & 1 deletion src/main/java/com/compiler/ast/ASTCallExprNode.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package com.compiler.ast;

import com.compiler.InstrBlock;
import com.compiler.InstrIntf;
import com.compiler.instr.InstrJump;
import com.compiler.instr.InstrPopValueStack;
import com.compiler.instr.InstrPushCallStack;
import com.compiler.instr.InstrPushValueStack;

import java.io.OutputStreamWriter;
import java.util.List;

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

@Override
public int eval() {
return 0;
return 0; // not implemented, as Call Expression only returns a value with prior function stmt
}

@Override
public void print(OutputStreamWriter outStream, String indent) throws Exception {
outStream.write(indent);
outStream.write("ASTCallExpressionNode ");
outStream.write("\n");
for (ASTExprNode astExprNode : m_argumentList) {
astExprNode.print(outStream, indent + " ");
}
}

@Override
public InstrIntf codegen(com.compiler.CompileEnvIntf env) {
m_argumentList.stream()
.map(arg -> arg.codegen(env))
.forEach(argInstr -> env.addInstr(new InstrPushValueStack(argInstr)));

env.addInstr(new InstrPushCallStack());

InstrBlock functionBodyBlock = env.getFunctionTable().getFunction(m_funcName).m_body;
env.addInstr(new InstrJump(functionBodyBlock));

InstrIntf popInstr = new InstrPopValueStack();
env.addInstr(popInstr);
return popInstr;
}

}
37 changes: 32 additions & 5 deletions src/main/java/com/compiler/ast/ASTFunctionStmtNode.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.compiler.ast;

import java.io.OutputStreamWriter;
import java.util.Collections;
import java.util.List;

import com.compiler.CompileEnvIntf;
import com.compiler.FunctionInfo;
import com.compiler.FunctionTable;
import com.compiler.InstrBlock;
import com.compiler.instr.InstrAssign;
import com.compiler.instr.InstrPopValueStack;

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

@Override
public void execute(OutputStreamWriter out) {

// nothing to do at runtime
}

@Override
public void codegen(CompileEnvIntf env) {
super.codegen(env);
InstrBlock codegenEntryBlock = env.getCurrentBlock();

InstrBlock functionBodyBlock = env.createBlock("function_"+m_functionName);
env.setCurrentBlock(functionBodyBlock);

m_parameterList.stream()
.sorted(Collections.reverseOrder())
.map(env.getSymbolTable()::getSymbol)
.forEach(parameter -> {
InstrPopValueStack popStackInstr = new InstrPopValueStack();
env.addInstr(popStackInstr);
InstrAssign assignInstr = new InstrAssign(parameter, popStackInstr);
env.addInstr(assignInstr);
});

m_functionBody.forEach(stmt -> stmt.codegen(env));

env.getFunctionTable().getFunction(m_functionName).m_body = functionBodyBlock;

env.setCurrentBlock(codegenEntryBlock);
}

@Override
public void print(OutputStreamWriter outStream, String indent) throws Exception {}
public void print(OutputStreamWriter outStream, String indent) throws Exception {
outStream.write(indent);
outStream.write("ASTFunctionStmtNode ");
outStream.write("\n");
for (ASTStmtNode astStmtNode : m_functionBody) {
astStmtNode.print(outStream, indent + " ");
}
}
}
16 changes: 14 additions & 2 deletions src/main/java/com/compiler/ast/ASTReturnStmtNode.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.compiler.ast;

import com.compiler.CompileEnvIntf;
import com.compiler.instr.InstrPushValueStack;
import com.compiler.instr.InstrReturn;

import java.io.OutputStreamWriter;

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

@Override
public void execute(OutputStreamWriter out) {

// nothing to do
}

@Override
public void print(OutputStreamWriter outStream, String indent) throws Exception {

outStream.write(indent);
outStream.write("ASTReturnStmtNode ");
outStream.write("\n");
m_expr.print(outStream, indent + " ");
}
@Override
public void codegen(CompileEnvIntf env) {
env.addInstr(new InstrPushValueStack(m_expr.codegen(env)));
env.addInstr(new InstrReturn());
}
}
23 changes: 23 additions & 0 deletions src/main/java/com/compiler/instr/InstrPopValueStack.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.compiler.instr;

import com.compiler.ExecutionEnvIntf;
import com.compiler.InstrIntf;

import java.io.OutputStreamWriter;

public class InstrPopValueStack extends InstrIntf {

public InstrPopValueStack() {}

@Override
public void execute(ExecutionEnvIntf env) throws Exception {
m_value = env.pop();
}

@Override
public void trace(OutputStreamWriter os) throws Exception {
os.write(String.format("%%%d = POP\n",
m_id
));
}
}
19 changes: 19 additions & 0 deletions src/main/java/com/compiler/instr/InstrPushCallStack.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.compiler.instr;

import com.compiler.ExecutionEnvIntf;
import com.compiler.InstrIntf;

import java.io.OutputStreamWriter;

public class InstrPushCallStack extends InstrIntf {
@Override
public void execute(ExecutionEnvIntf env) throws Exception {
env.pushReturnAddr(env.getInstrIter());
}

@Override
public void trace(OutputStreamWriter os) throws Exception {
os.write("PUSH_RETURN_ADDR\n");

}
}
25 changes: 25 additions & 0 deletions src/main/java/com/compiler/instr/InstrPushValueStack.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.compiler.instr;

import com.compiler.ExecutionEnvIntf;
import com.compiler.InstrIntf;

import java.io.OutputStreamWriter;

public class InstrPushValueStack extends InstrIntf {
InstrIntf m_instruction;
public InstrPushValueStack(InstrIntf instruction) {
m_instruction = instruction;
}

@Override
public void execute(ExecutionEnvIntf env) throws Exception {
env.push(m_instruction.getValue());
}

@Override
public void trace(OutputStreamWriter os) throws Exception {
os.write(String.format("PUSH %%%d\n",
m_instruction.getId()
));
}
}
18 changes: 18 additions & 0 deletions src/main/java/com/compiler/instr/InstrReturn.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.compiler.instr;

import com.compiler.ExecutionEnvIntf;
import com.compiler.InstrIntf;

import java.io.OutputStreamWriter;

public class InstrReturn extends InstrIntf {
@Override
public void execute(ExecutionEnvIntf env) throws Exception {
env.setInstrIter(env.popReturnAddr());
}

@Override
public void trace(OutputStreamWriter os) throws Exception {
os.write("JUMP POP_RETURN_ADDR");
}
}
Loading