Skip to content

Commit

Permalink
(wip) first code gen base
Browse files Browse the repository at this point in the history
TODO: bif and assignment
  • Loading branch information
gabrielegenovese committed Jul 8, 2024
1 parent f0692ff commit e3780ba
Show file tree
Hide file tree
Showing 28 changed files with 451 additions and 69 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ out/
trees/
.project
.vscode/
src/parser/.antlr/
src/parser/.antlr/
code.asm
13 changes: 13 additions & 0 deletions src/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
import org.antlr.v4.gui.TreeViewer;
import org.antlr.v4.runtime.*;

import java.nio.file.StandardOpenOption;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import ast.*;
import ast.nodes.*;
import parser.*;
Expand Down Expand Up @@ -62,6 +67,14 @@ public static void main(String[] args) {
} else {
System.out.println("Visualizing AST...");
System.out.println(ast.toPrint(""));
System.out.println("Creating VM code...");
String prog = ast.codeGeneration();
Path file = Paths.get("code.asm");
if(!Files.exists(file)) {
Files.createFile(file);
}
Files.write(file, prog.getBytes(), StandardOpenOption.TRUNCATE_EXISTING);
System.out.println("Done!");
}
} catch (Exception e) {
e.printStackTrace();
Expand Down
20 changes: 10 additions & 10 deletions src/ast/Python3VisitorImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -336,32 +336,32 @@ public Node visitBlock(BlockContext ctx) {
}

/**
* Returns a `CompNode`. It should never be null.
* Returns a `CompOpNode`. It should never be null.
*
* ``` comp_op : '<' | '>' | '==' | '>=' | '<=' | '<>' | '!=' | 'in' | 'not'
* 'in' | 'is' | 'is' 'not' ; ```
*/
public Node visitComp_op(Comp_opContext ctx) {
Node comp = null;
if (ctx.LESS_THAN() != null) {
comp = new CompNode(ctx.LESS_THAN());
comp = new CompOpNode(ctx.LESS_THAN());
} else if (ctx.GREATER_THAN() != null) {
comp = new CompNode(ctx.GREATER_THAN());
comp = new CompOpNode(ctx.GREATER_THAN());
} else if (ctx.EQUALS() != null) {
comp = new CompNode(ctx.EQUALS());
comp = new CompOpNode(ctx.EQUALS());
} else if (ctx.GT_EQ() != null) {
comp = new CompNode(ctx.GT_EQ());
comp = new CompOpNode(ctx.GT_EQ());
} else if (ctx.LT_EQ() != null) {
comp = new CompNode(ctx.LT_EQ());
comp = new CompOpNode(ctx.LT_EQ());
} else if (ctx.NOT_EQ_2() != null) {
// We're ignoring NOT_EQ_1() because no one uses `<>`
comp = new CompNode(ctx.NOT_EQ_2());
comp = new CompOpNode(ctx.NOT_EQ_2());
} else if (ctx.IN() != null) {
comp = new CompNode(ctx.IN());
comp = new CompOpNode(ctx.IN());
} else if (ctx.NOT() != null) {
comp = new CompNode(ctx.NOT());
comp = new CompOpNode(ctx.NOT());
} else if (ctx.IS() != null) {
comp = new CompNode(ctx.IS());
comp = new CompOpNode(ctx.IS());
}

return comp;
Expand Down
7 changes: 5 additions & 2 deletions src/ast/nodes/ArglistNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,13 @@ public Type typeCheck() {
return new VoidType();
}

// TODO: add code generation for arglist node
@Override
public String codeGeneration() {
return "";
String str = "";
for (Node arg : arguments) {
str += arg.codeGeneration() + "pushr A0\n";
}
return str;
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion src/ast/nodes/AssignmentNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
// ExprNode ratom = (ExprNode) rhr.getElem(i);
}
// } else {
// FIX: sgravata da più problemi che altro
// FIX: sgravata, da più problemi che altro
// errors.add(new SemanticError("ValueError: different size of left or right side assignment"));
// }

Expand Down
48 changes: 37 additions & 11 deletions src/ast/nodes/AtomNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import semanticanalysis.STentry;
import semanticanalysis.SemanticError;
import semanticanalysis.SymbolTable;

Expand All @@ -13,30 +14,33 @@
public class AtomNode implements Node {

protected String val;
protected STentry entry;
protected TestlistCompNode exprlist;

public AtomNode(String val, Node exprlist) {
this.val = val;
this.exprlist = (TestlistCompNode) exprlist;
this.entry = null;
}

/**
* Returns the identifier of the `AtomNode` if it's not `null`, otherwise
* returns `null`.
*/
public String getId() {
return this.val;
return val;
}

@Override
public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
ArrayList<SemanticError> errors = new ArrayList<>();

if (val != null) {
if ((this.typeCheck() instanceof AtomType) && ST.nslookup(this.getId()) < 0) {
errors.add(new SemanticError("name '" + this.getId() + "' is not defined."));
if ((typeCheck() instanceof AtomType) && ST.nslookup(getId()) < 0) {
errors.add(new SemanticError("name '" + getId() + "' is not defined."));
} else {
// System.out.println("exist " + this.typeCheck());
// System.out.println("exist " + typeCheck());
entry = ST.lookup(getId());
}
}

Expand All @@ -50,29 +54,34 @@ public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
// ENHANCE: return more specific types
@Override
public Type typeCheck() {
if (this.val == null) {
if (val == null) {
return new VoidType();
}

Pattern noneVariable = Pattern.compile("^(None)$");
Pattern booleanVariable = Pattern.compile("^(True|False)$");
Pattern integerVariable = Pattern.compile("^[0-9]+$");
Pattern reservedWords = Pattern.compile("^(continue|break|int|float)$");
// this regex should match every possible atom name written in this format: CHAR
// (CHAR | DIGIT)*
Pattern simpleVariable = Pattern.compile("^[a-zA-Z][a-zA-Z0-9]*$", Pattern.CASE_INSENSITIVE);

Matcher noneVariableMatcher = noneVariable.matcher(this.val);
Matcher booleanVariableMatcher = booleanVariable.matcher(this.val);
Matcher reservedWordsMatcher = reservedWords.matcher(this.val);
Matcher simpleVariableMatcher = simpleVariable.matcher(this.val);
Matcher noneVariableMatcher = noneVariable.matcher(val);
Matcher booleanVariableMatcher = booleanVariable.matcher(val);
Matcher integerVariableMatcher = integerVariable.matcher(val);
Matcher reservedWordsMatcher = reservedWords.matcher(val);
Matcher simpleVariableMatcher = simpleVariable.matcher(val);

boolean matchFoundNone = noneVariableMatcher.find();
boolean matchFoundBoolean = booleanVariableMatcher.find();
boolean matchFoundInteger = integerVariableMatcher.find();
boolean matchFoundContinueBreak = reservedWordsMatcher.find();
boolean matchFoundSimpleVariable = simpleVariableMatcher.find();

if (matchFoundBoolean) {
return new BoolType();
} else if (matchFoundInteger) {
return new IntType();
} else if (matchFoundContinueBreak) {
return new ReservedWordsType();
} else if (matchFoundNone) {
Expand All @@ -84,10 +93,27 @@ public Type typeCheck() {
}
}

// TODO: add code generation for atom node
@Override
public String codeGeneration() {
return "";
String base = "storei A0 ";

if(exprlist != null) {
return exprlist.codeGeneration();
}
if (typeCheck() instanceof IntType) {
return base + getId() + "\n";
}
if (typeCheck() instanceof BoolType) {
return base + boolValue(getId()) + "\n";
}
if (typeCheck() instanceof AtomType) {
return base + "-" + String.valueOf(entry.getOffset()) + "(FP)\n" ;
}
return "Error: could not parse an atom\n";
}

public static String boolValue(String id) {
return id == "True" ? "1" : "0";
}

@Override
Expand Down
11 changes: 11 additions & 0 deletions src/ast/nodes/BlockNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ public Type typeCheck() {
return new VoidType();
}

@Override
public String codeGeneration() {
String str = "";

for (Node child : childs) {
str += child.codeGeneration();
}

return str;
}

@Override
public String toPrint(String prefix) {
String str = prefix + "Block\n";
Expand Down
2 changes: 1 addition & 1 deletion src/ast/nodes/CompForNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public Type typeCheck() {
return new VoidType();
}

// TODO: add code generation for arglist node
// TODO: add code generation for comp_for node
@Override
public String codeGeneration() {
return "";
Expand Down
2 changes: 1 addition & 1 deletion src/ast/nodes/CompIterNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public Type typeCheck() {
return new VoidType();
}

// TODO: add code generation for arglist node
// TODO: add code generation for comp_iter node
@Override
public String codeGeneration() {
return "";
Expand Down
12 changes: 8 additions & 4 deletions src/ast/nodes/CompNode.java → src/ast/nodes/CompOpNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@
/**
* Node for the `comp_op` statement of the grammar.
*/
public class CompNode implements Node {
public class CompOpNode implements Node {

private final TerminalNode op;

public CompNode(TerminalNode op) {
public CompOpNode(TerminalNode op) {
this.op = op;
}

public String getOp() {
return op.toString();
}

@Override
public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
return new ArrayList<>();
Expand All @@ -29,14 +33,14 @@ public Type typeCheck() {
return new VoidType();
}

// TODO: add code generation for CompNode
// TODO: add code generation for CompOpNode
@Override
public String codeGeneration() {
return "";
}

@Override
public String toPrint(String prefix) {
return prefix + "CompNode(" + op + ")\n";
return prefix + "CompOpNode(" + op + ")\n";
}
}
19 changes: 17 additions & 2 deletions src/ast/nodes/CompoundNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,25 @@ public Type typeCheck() {
return new VoidType();
}

// TODO: add code generation for CompoundNode
@Override
public String codeGeneration() {
return "";
if (ifNode != null) {
return ifNode.codeGeneration();
}

if (funcDef != null) {
return funcDef.codeGeneration();
}

if (forStmt != null) {
return forStmt.codeGeneration();
}

if (whileStmt != null) {
return whileStmt.codeGeneration();
}

return "Error: everything is null in Compound node\n";
}

@Override
Expand Down
9 changes: 7 additions & 2 deletions src/ast/nodes/ExprListNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,15 @@ public Type typeCheck() {
return new VoidType();
}

// TODO: code generation for expr list
@Override
public String codeGeneration() {
return "";
String str = "";

for (var param : exprs) {
str += param.codeGeneration();
}

return str;
}

@Override
Expand Down
Loading

0 comments on commit e3780ba

Please sign in to comment.