finalwq
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
|
||||
def hello(x:Int) =
|
||||
new Array[Int](x + getchar());
|
||||
val arr = hello(5);
|
||||
arr(0) = toInt('H'); arr(1) = toInt('e'); arr(2) = toInt('l'); arr(3) = toInt('l'); arr(4) = toInt('o');
|
||||
putchar(arr(3));putchar(arr(4));putchar(arr(2));arr(0)
|
||||
@@ -0,0 +1,17 @@
|
||||
def even(x: Int) : Boolean =
|
||||
toInt(toChar(x * 128)) == 0;
|
||||
def pow(x: Int, y: Int): Int =
|
||||
if (y == 0) 1
|
||||
else if (even(y)) {
|
||||
val t = pow(x, y / 2);
|
||||
t*t
|
||||
} else {
|
||||
x * pow(x, y - 1)
|
||||
};
|
||||
var i = 30; var res = 0;
|
||||
|
||||
while(i > 0) {
|
||||
res = res + pow(2, i);
|
||||
i = i - 1; ()
|
||||
};
|
||||
res
|
||||
@@ -0,0 +1,7 @@
|
||||
var x = 2;
|
||||
var y = 0;
|
||||
while ({ if (y < 3) true else y < 4}) {
|
||||
x = x * x;
|
||||
y = y + 1; ()
|
||||
};
|
||||
x
|
||||
@@ -350,7 +350,9 @@ abstract class X86Compiler extends BugReporter with Codegen {
|
||||
val fLoc: String = fun match {
|
||||
case Ref(fname) =>
|
||||
env(fname) match {
|
||||
case Reg(sp) => s"*${loc(sp)}" // Extra credit
|
||||
case Reg(sp) =>
|
||||
emitln(s"movq ${loc(sp)}, %rax")
|
||||
s"*%rax" // Extra credit
|
||||
case Func(name) => funcName(name) // TODO
|
||||
}
|
||||
case _ => // return from another invocation
|
||||
@@ -384,11 +386,10 @@ abstract class X86Compiler extends BugReporter with Codegen {
|
||||
// the assembly variable "heap" contains a pointer to the first valid byte
|
||||
// in the heap. Make sure to update its value accordingly.
|
||||
// TODO
|
||||
emitln(s"movq (%rip), ${loc(sp)}")
|
||||
emitln(s"movq heap, ${loc(sp)}")
|
||||
trans(size, sp + 1)(env)
|
||||
emitln(s"movq (%rip), ${loc(sp + 2)}")
|
||||
emitln(s"movq (${loc(sp + 2)}, ${loc(sp + 1)}, 8), ${loc(sp + 2)}")
|
||||
emitln(s"movq ${loc(sp + 2)}, %rip")
|
||||
emitln(s"shlq $$3, ${loc(sp + 1)}")
|
||||
emitln(s"addq ${loc(sp + 1)}, heap")
|
||||
case _ => BUG(s"don't know how to implement $exp")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ OPTION: intStack""")
|
||||
} else {
|
||||
args(0)
|
||||
}
|
||||
//val src = "var x = 2; while (x<777) {x = x + 2;putchar(x)};x"
|
||||
println("============ SRC CODE ============")
|
||||
println(src)
|
||||
println("==================================\n")
|
||||
|
||||
@@ -520,7 +520,10 @@ class BaseParser(in: Scanner) extends Parser(in) {
|
||||
val res = parseExpression
|
||||
accept('}')
|
||||
res
|
||||
case _ => abort(s"Illegal start of simple expression")
|
||||
case _ =>
|
||||
println(in.peek)
|
||||
println(in.peek1)
|
||||
abort(s"Illegal start of simple expression")
|
||||
}
|
||||
|
||||
def parseUAtom: Exp = if (in.hasNext(isOperator)) {
|
||||
@@ -579,7 +582,7 @@ class BaseParser(in: Scanner) extends Parser(in) {
|
||||
val body = parseExpression
|
||||
VarDec(name, tp, rhs, body).withPos(pos)
|
||||
case Keyword("while") =>
|
||||
val pos = accept("while").pos
|
||||
val pos = in.next().pos
|
||||
accept('(')
|
||||
val cond = parseSimpleExpression
|
||||
accept(')')
|
||||
@@ -648,7 +651,7 @@ class SyntacticSugarParser(in: Scanner) extends BaseParser(in) {
|
||||
suf + "$" + next
|
||||
}
|
||||
|
||||
override def parseSimpleExpression = in.peek match { // !!!
|
||||
override def parseSimpleExpression = in.peek match {
|
||||
case Keyword("if") =>
|
||||
val pos = in.next().pos
|
||||
accept('(')
|
||||
@@ -667,18 +670,12 @@ class SyntacticSugarParser(in: Scanner) extends BaseParser(in) {
|
||||
|
||||
override def parseExpression = {
|
||||
// NOTE: parse expression terminates when it parse a simples expression.
|
||||
// syntax sugar allows to have an other expression after it. !!!
|
||||
var res = in.peek match {
|
||||
case Keyword("val") | Keyword("var") | Keyword("while") =>
|
||||
super.parseExpression
|
||||
case _ =>
|
||||
var simp = parseSimpleExpression
|
||||
if(isNewLine(in.peek)) {
|
||||
accept(';')
|
||||
simp = Let(freshName(), UnknownType, simp, parseExpression).withPos(simp.pos)
|
||||
}
|
||||
simp
|
||||
}
|
||||
// syntax sugar allows to have an other expression after it.
|
||||
var res = super.parseExpression
|
||||
if(in.hasNext(_ match {case Delim(';') => true; case _ => false})){
|
||||
accept(';')
|
||||
res = Let(freshName(), UnknownType, res, parseExpression).withPos(res.pos)
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
@@ -764,30 +761,24 @@ class FunctionParser(in: Scanner) extends SyntacticSugarParser(in) {
|
||||
/*
|
||||
* This function parse types.
|
||||
*
|
||||
* TODO !!!
|
||||
* TODO
|
||||
*/
|
||||
override def parseType = in.peek match {
|
||||
case Delim('(') =>
|
||||
case Delim('(') =>
|
||||
accept('(')
|
||||
val list = parseList[Type](parseType, ',', tok => tok match {
|
||||
case Delim(')') => false;
|
||||
case _ => true
|
||||
val list = parseList[Type](parseType, ',', _ match {
|
||||
case Delim(')') => false; case _ => true
|
||||
})
|
||||
val argList = list map { tp => ("", tp)}
|
||||
val args = list map { tp => ("", tp)}
|
||||
accept("=>")
|
||||
val rtp = parseType
|
||||
FunType(argList, rtp)
|
||||
FunType(args, parseType)
|
||||
case _ =>
|
||||
val typ = super.parseType
|
||||
if(in.peek == Delim('=') && in.peek1 == Ident(">")) {
|
||||
accept("=>")
|
||||
val rtp = super.parseType
|
||||
val typList: List[(String, Type)] = List(("", typ))
|
||||
FunType(typList, rtp)
|
||||
}
|
||||
else {
|
||||
typ
|
||||
}
|
||||
var ty = super.parseType
|
||||
if(in.peek == Delim('=') && in.peek1 == Ident(">")) {
|
||||
accept("=>")
|
||||
ty = FunType(List(("", ty)), super.parseType)
|
||||
}
|
||||
ty
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -369,7 +369,7 @@ class SemanticAnalyzer(parser: Parser) extends Reporter with BugReporter {
|
||||
*/
|
||||
pt match {
|
||||
case UnitType | IntType | BooleanType | CharType => VarAssign(x, rhsChecked).withType(rhsChecked.tp)
|
||||
case _ => exp.withType(UnknownType)
|
||||
case _ => exp.withType(UnitType)
|
||||
}
|
||||
case While(cond, lbody, body) =>
|
||||
val condChecked = typeCheck(cond, BooleanType)(env)
|
||||
@@ -389,9 +389,9 @@ class SemanticAnalyzer(parser: Parser) extends Reporter with BugReporter {
|
||||
|
||||
case LetRec(funs, body) =>
|
||||
// TODO modify to handle general case
|
||||
val _env = env.withVals(funs.map {case FunDef(name, _, rtp, _) => (name, rtp)})
|
||||
val funsChecked = funs map {case f@FunDef(_, _, rtp, _) => typeCheck(f, rtp)(_env) }
|
||||
val bodyChecked = typeCheck(body, pt)( env.withVals(funsChecked map {case FunDef(name, _, rtp, _) => (name, rtp)}))
|
||||
val _env = env.withVals(funs map {case FunDef(name, args, rtp, _) => (name, funType(args, rtp))})
|
||||
val funsChecked = funs map {case f@FunDef(_, args, rtp, _) => typeCheck(f, funType(args, rtp))(_env) }
|
||||
val bodyChecked = typeCheck(body, pt)( env.withVals(funsChecked map {case FunDef(name, args, rtp, _) => (name, funType(args, rtp))}))
|
||||
LetRec(funsChecked, bodyChecked).withType(bodyChecked.tp)
|
||||
|
||||
case App(fun, args) =>
|
||||
|
||||
@@ -38,4 +38,20 @@ class CompilerTest extends TimedSuite {
|
||||
testCompiler(LetRec(Nil, Prim("-", List(Lit(10), Lit(2)))), 8)
|
||||
}
|
||||
|
||||
test("extra_credit_fn_as_var") {
|
||||
testCompiler(LetRec(Nil,Let("x",UnknownType,Ref("putchar"),Let("x$1",UnknownType,App(Ref("x"),List(Lit(97))),Lit(69)))), 69)
|
||||
}
|
||||
|
||||
test("extra_credit_char_parse_toInt_toChar") {
|
||||
testCompiler(LetRec(Nil,Let("x$1",UnitType,App(Ref("putchar"),List(App(Ref("toInt"),List(Lit('s'))))),Let("x$2",UnitType,App(Ref("putchar"),List(App(Ref("toInt"),List(Lit('s'))))),Let("x$3",UnitType,App(Ref("putchar"),List(App(Ref("toInt"),List(Lit('i'))))),Lit(96))))), 96)
|
||||
testCompiler(LetRec(List(),App(Ref("toInt"),List(App(Ref("toChar"),List(Lit(420)))))), 164) // Int->Char narrow
|
||||
}
|
||||
|
||||
test("func_decl_call") {
|
||||
val pos = Position(0,0,0,0,0,0)
|
||||
//def f(x:Int, y:Int, z:Char) = (x - y)*20 + 10 * toInt(z); f(6, 9, '0') == 420
|
||||
testCompiler(LetRec(List(FunDef("f",List(Arg("x",IntType,pos), Arg("y",IntType,Position(0,0,0,0,0,0)), Arg("z",CharType,Position(0,0,0,0,0,0))),IntType,Prim("+",List(Prim("*",List(Prim("-",List(Ref("x"), Ref("y"))), Lit(20))), Prim("*",List(Lit(10), App(Ref("toInt"),List(Ref("z"))))))))),App(Ref("f"),List(Lit(6), Lit(9), Lit('0')))), 420)
|
||||
//def f(x:Int) = 1 + x; val y = f(1); val z = f(2); y + z
|
||||
testCompiler(LetRec(List(FunDef("f",List(Arg("x",IntType,pos)),IntType,Prim("+",List(Lit(1), Ref("x"))))),Let("y",IntType,App(Ref("f"),List(Lit(1))),Let("z",IntType,App(Ref("f"),List(Lit(2))),Prim("+",List(Ref("y"), Ref("z")))))), 5)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,4 +17,20 @@ class InterpretTest extends TimedSuite {
|
||||
testInterpreter(Prim("-", List(Lit(10), Lit(2))), Cst(8))
|
||||
}
|
||||
|
||||
// test("extra_credit_fn_as_var") {
|
||||
// testInterpreter(LetRec(Nil,Let("x",UnknownType,Ref("putchar"),Let("x$1",UnknownType,App(Ref("x"),List(Lit(97))),Lit(69)))), Cst(69))
|
||||
// }
|
||||
|
||||
// test("extra_credit_char_parse_toInt_toChar") {
|
||||
// testInterpreter(LetRec(Nil,Let("x$1",UnitType,App(Ref("putchar"),List(App(Ref("toInt"),List(Lit('s'))))),Let("x$2",UnitType,App(Ref("putchar"),List(App(Ref("toInt"),List(Lit('s'))))),Let("x$3",UnitType,App(Ref("putchar"),List(App(Ref("toInt"),List(Lit('i'))))),Lit(96))))), Cst(96))
|
||||
// testInterpreter(LetRec(List(),App(Ref("toInt"),List(App(Ref("toChar"),List(Lit(420)))))), Cst(164)) // Int->Char narrow
|
||||
// }
|
||||
|
||||
// test("func_decl_call") {
|
||||
// val pos = Position(0,0,0,0,0,0)
|
||||
// //def f(x:Int, y:Int, z:Char) = (x - y)*20 + 10 * toInt(z); f(6, 9, '0') == 420
|
||||
// testInterpreter(LetRec(List(FunDef("f",List(Arg("x",IntType,pos), Arg("y",IntType,Position(0,0,0,0,0,0)), Arg("z",CharType,Position(0,0,0,0,0,0))),IntType,Prim("+",List(Prim("*",List(Prim("-",List(Ref("x"), Ref("y"))), Lit(20))), Prim("*",List(Lit(10), App(Ref("toInt"),List(Ref("z"))))))))),App(Ref("f"),List(Lit(6), Lit(9), Lit('0')))), Cst(420))
|
||||
// //def f(x:Int) = 1 + x; val y = f(1); val z = f(2); y + z
|
||||
// testInterpreter(LetRec(List(FunDef("f",List(Arg("x",IntType,pos)),IntType,Prim("+",List(Lit(1), Ref("x"))))),Let("y",IntType,App(Ref("f"),List(Lit(1))),Let("z",IntType,App(Ref("f"),List(Lit(2))),Prim("+",List(Ref("y"), Ref("z")))))), Cst(5))
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -30,4 +30,5 @@ class ParserTest extends TimedSuite {
|
||||
test("ParseOptionalType") {
|
||||
testBaseParser("val x = 1; 2", Let("x", UnknownType, Lit(1), Lit(2)))
|
||||
}
|
||||
//see examples/hello.scala and pow.scala for more comprehensive tests
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user