Skip to content

Commit

Permalink
Merge pull request #9 from kbrabrand/code-gen
Browse files Browse the repository at this point in the history
Code generation
  • Loading branch information
kbrabrand committed Dec 1, 2015
2 parents 54b0cc6 + 7e58325 commit 102cdad
Show file tree
Hide file tree
Showing 50 changed files with 723 additions and 173 deletions.
Binary file added libpas2100.a
Binary file not shown.
16 changes: 16 additions & 0 deletions libpas2100.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include <stdio.h>

void write_char (int c)
{
printf("%c", c);
}

void write_int (int n)
{
printf("%d", n);
}

void write_string (char *s)
{
printf("%s", s);
}
Binary file added libpas2100.o
Binary file not shown.
8 changes: 8 additions & 0 deletions no/uio/ifi/pascal2100/main/CodeFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ public void genInstr(String lab, String instr, String arg, String comment) {
code.println();
}

public void genInstr(String lab, String instr, String arg) {
this.genInstr(lab, instr, arg, "");
}

public void genInstr(String lab, String instr) {
this.genInstr(lab, instr, "", "");
}

public void genString(String name, String s, String comment) {
genDirective(".data", "");
printLabel(name, false);
Expand Down
4 changes: 3 additions & 1 deletion no/uio/ifi/pascal2100/main/LogFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ public void noteToken(Token tok) {
*/

public void noteBinding(String id, PascalSyntax where, PascalDecl decl) {
if (doLogBinding) {
if (doLogBinding && !where.isBindingNoted) {
where.isBindingNoted = true;

writeLogLine(
"Binding on line " + where.lineNum + ": " + id +
" was declared in " + decl.identify()
Expand Down
17 changes: 9 additions & 8 deletions no/uio/ifi/pascal2100/main/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -113,18 +113,19 @@ private static void doRunRealCompiler(Scanner s) {
System.out.print(" checking...");

library = new Library();
prog.check(library, library);
library.check(library, library, null);

/* Del 4
* System.out.print(" generating code...");
* CodeFile code = new CodeFile(baseFileName+".s");
* library.genCode(code); prog.genCode(code);
* code.finish();
*/
prog.check(library, library, null);

System.out.print(" generating code...");
CodeFile code = new CodeFile(baseFileName+".s");
library.genCode(code);
prog.genCode(code);
code.finish();

System.out.println("OK");

// Del 4: assembleCode();
assembleCode();
}

private static void assembleCode() {
Expand Down
34 changes: 30 additions & 4 deletions no/uio/ifi/pascal2100/parser/ArrayType.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package no.uio.ifi.pascal2100.parser;

import no.uio.ifi.pascal2100.main.CodeFile;
import no.uio.ifi.pascal2100.main.Main;
import no.uio.ifi.pascal2100.scanner.Scanner;

import no.uio.ifi.pascal2100.parser.NumberLiteral;
import static no.uio.ifi.pascal2100.scanner.TokenKind.arrayToken;
import static no.uio.ifi.pascal2100.scanner.TokenKind.leftBracketToken;
import static no.uio.ifi.pascal2100.scanner.TokenKind.rightBracketToken;
Expand Down Expand Up @@ -42,10 +44,29 @@ public static ArrayType parse(Scanner s) {
return at;
}

@Override
public void check(Block curScope, Library lib) {
type.check(curScope, lib);
ofType.check(curScope, lib);
private RangeType getRange() {
Type curType = type;

while (!(curType instanceof RangeType)) {
curType = ((TypeName) curType).decl.type;
}

return (RangeType) curType;
}

public int getLow() {
NumberLiteral low = (NumberLiteral) getRange().from;
return low.val;
}

public int getHigh() {
NumberLiteral high = (NumberLiteral) getRange().to;
return high.val;
}

public void check(Block curScope, Library lib, Expression e) {
type.check(curScope, lib, e);
ofType.check(curScope, lib, e);
}

void prettyPrint() {
Expand All @@ -54,4 +75,9 @@ void prettyPrint() {
Main.log.prettyPrint("] of ");
ofType.prettyPrint();
}

@Override
void genCode(CodeFile f) {
// TODO Auto-generated method stub
}
}
21 changes: 18 additions & 3 deletions no/uio/ifi/pascal2100/parser/AssignStatm.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static no.uio.ifi.pascal2100.scanner.TokenKind.assignToken;

import no.uio.ifi.pascal2100.main.CodeFile;
import no.uio.ifi.pascal2100.main.Main;
import no.uio.ifi.pascal2100.scanner.Scanner;

Expand Down Expand Up @@ -33,14 +34,28 @@ public static AssignStatm parse(Scanner s) {
}

@Override
public void check(Block curScope, Library lib) {
var.check(curScope, lib);
expr.check(curScope, lib);
public void check(Block curScope, Library lib, Expression e) {
var.check(curScope, lib, e);
expr.check(curScope, lib, e);
}

void prettyPrint() {
var.prettyPrint();
Main.log.prettyPrint(" := ");
expr.prettyPrint();
}

public void genCode(CodeFile f) {
expr.genCode(f);

// Assign function return value
if (var.nameDecl instanceof FuncDecl) {
f.genInstr("", "movl", "%eax,-32(%ebp)");
return;
}

// Simple variable assignment
f.genInstr("", "movl", "-" + (4 * var.nameDecl.declLevel) + "(%ebp),%edx");
f.genInstr("", "movl", "%eax," + var.nameDecl.declOffset + "(%edx)", var.name + " :=");
}
}
73 changes: 57 additions & 16 deletions no/uio/ifi/pascal2100/parser/Block.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.HashMap;
import java.util.LinkedList;

import no.uio.ifi.pascal2100.main.CodeFile;
import no.uio.ifi.pascal2100.main.Main;
import no.uio.ifi.pascal2100.scanner.Scanner;

Expand All @@ -22,6 +23,7 @@ public class Block extends PascalSyntax {
public VarDeclPart varDeclPart = null;
public LinkedList<ProcDecl> procDeclList = new LinkedList<ProcDecl>();

int blockLevel = 0;
Block outerScope = null;
HashMap<String, PascalDecl> decls = new HashMap<String, PascalDecl>();

Expand Down Expand Up @@ -94,6 +96,14 @@ public PascalDecl findDecl(String id, PascalSyntax where) {
}

public void addDecl(String id, PascalDecl decl) {
// Because we're recursing through the tree, different check paths may call addDecl
// on the same object, but since the AST contains only unique nodes and the tree has been
// validated we can safely skip adding them if we already have the exact same node in
// the decls map for this particular scope
if (decls.containsValue(decl)) {
return;
}

if (decls.containsKey(id.toLowerCase())) {
decl.error(id + " declared twice in same block");
}
Expand All @@ -107,18 +117,42 @@ public void addDecl(String id, PascalDecl decl) {
* @param outerScope
* @param curScope
* @param lib
* @param e
*/
public void check(Block outerScope, Block curScope, Library lib) {
public void check(Block outerScope, Block curScope, Library lib, Expression e) {
// If we're trying to set the outer scope on an block that has the outer scope
// set already, we're about to check the same subtree over again. Return here to
// prevent an infinite loop
if (curScope.outerScope != null) {
return;
}

curScope.blockLevel = outerScope.blockLevel + 1;
curScope.outerScope = outerScope;

check(curScope, lib);
check(curScope, lib, e);
}

@Override
public void check(Block curScope, Library lib) {
public void check(Block curScope, Library lib, Expression e) {
// Variable declarations
if (varDeclPart != null) {
varDeclPart.check(this, lib, e);

VarDecl vd;
for (int i = 0; i < varDeclPart.decls.size(); i++) {
vd = varDeclPart.decls.get(i);

vd.declLevel = blockLevel;
vd.declOffset = -36 - (i * 4);

this.addDecl(vd.name, vd);
}
}

// Constant declarations
if (constDeclPart != null) {
constDeclPart.check(this, lib);
constDeclPart.check(this, lib, e);

for (ConstDecl cd: constDeclPart.decls) {
this.addDecl(cd.name, cd);
Expand All @@ -127,28 +161,19 @@ public void check(Block curScope, Library lib) {

// Type declarations
if (typeDeclPart != null) {
typeDeclPart.check(this, lib);
typeDeclPart.check(this, lib, e);

for (TypeDecl td: typeDeclPart.decls) {
this.addDecl(td.name.name, td);
}
}

// Variable declarations
if (varDeclPart != null) {
varDeclPart.check(this, lib);

for (VarDecl vd: varDeclPart.decls) {
this.addDecl(vd.name, vd);
}
}

// Procedure declarations
for (ProcDecl pd : procDeclList) {
pd.check(curScope, lib);
pd.check(curScope, lib, e);
}

stmtList.check(this, lib);
stmtList.check(curScope, lib, e);
}

public void prettyPrint() {
Expand Down Expand Up @@ -185,4 +210,20 @@ public void prettyPrint() {
Main.log.prettyOutdent();
Main.log.prettyPrint("end");
}

/**
* Get number of bytes that should be allocated for this block. 32 + (number-of-variables * 4)
*
* @return integer Number of bytes
*/
int getSize() {
return 32 + (varDeclPart != null ? varDeclPart.decls.size() * 4 : 0);
}

@Override
public void genCode(CodeFile f) {
if (stmtList != null) {
stmtList.genCode(f);
}
}
}
14 changes: 13 additions & 1 deletion no/uio/ifi/pascal2100/parser/CharLiteral.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package no.uio.ifi.pascal2100.parser;

import no.uio.ifi.pascal2100.main.CodeFile;
import no.uio.ifi.pascal2100.main.Main;
import no.uio.ifi.pascal2100.scanner.Scanner;

Expand Down Expand Up @@ -29,10 +30,21 @@ public static CharLiteral parse(Scanner s) {
}

@Override
public void check(Block curScope, Library lib) { }
public void check(Block curScope, Library lib, Expression e) {
if (e != null) {
e.isChar = true;
}
}

@Override
void prettyPrint() {
Main.log.prettyPrint("'" + String.valueOf(val) + "'");
}

@Override
void genCode(CodeFile f) {
int intVal = (int) val;

f.genInstr("", "movl", "$" + intVal + ",%eax", " char " + intVal);
}
}
10 changes: 8 additions & 2 deletions no/uio/ifi/pascal2100/parser/CompoundStatm.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static no.uio.ifi.pascal2100.scanner.TokenKind.beginToken;
import static no.uio.ifi.pascal2100.scanner.TokenKind.endToken;

import no.uio.ifi.pascal2100.main.CodeFile;
import no.uio.ifi.pascal2100.main.Main;
import no.uio.ifi.pascal2100.scanner.Scanner;

Expand Down Expand Up @@ -33,8 +34,8 @@ public static CompoundStatm parse(Scanner s) {
}

@Override
public void check(Block curScope, Library lib) {
stmtList.check(curScope, lib);
public void check(Block curScope, Library lib, Expression e) {
stmtList.check(curScope, lib, e);
}

@Override
Expand All @@ -47,4 +48,9 @@ void prettyPrint() {
Main.log.prettyOutdent();
Main.log.prettyPrint("end");
}

@Override
void genCode(CodeFile f) {
stmtList.genCode(f);
}
}
4 changes: 2 additions & 2 deletions no/uio/ifi/pascal2100/parser/ConstDecl.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ public static ConstDecl parse(Scanner s) {
}

@Override
public void check(Block curScope, Library lib) {
constant.check(curScope, lib);
public void check(Block curScope, Library lib, Expression e) {
constant.check(curScope, lib, e);
}

public void prettyPrint() {
Expand Down
4 changes: 2 additions & 2 deletions no/uio/ifi/pascal2100/parser/ConstDeclPart.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ public static ConstDeclPart parse(Scanner s) {
}

@Override
public void check(Block curScope, Library lib) {
public void check(Block curScope, Library lib, Expression e) {
for (ConstDecl cd : decls) {
cd.check(curScope, lib);
cd.check(curScope, lib, e);
}
}

Expand Down
2 changes: 1 addition & 1 deletion no/uio/ifi/pascal2100/parser/Constant.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import no.uio.ifi.pascal2100.scanner.Scanner;

abstract class Constant extends Factor {
Constant(int lNum) {
Constant(int lNum) {
super(lNum);
}

Expand Down
3 changes: 0 additions & 3 deletions no/uio/ifi/pascal2100/parser/EmptyStatm.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ public static EmptyStatm parse(Scanner s) {
return es;
}

@Override
public void check(Block curScope, Library lib) { }

@Override
void prettyPrint() {
Main.log.prettyPrint(";");
Expand Down
Loading

0 comments on commit 102cdad

Please sign in to comment.