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 {
|
val fLoc: String = fun match {
|
||||||
case Ref(fname) =>
|
case Ref(fname) =>
|
||||||
env(fname) match {
|
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 Func(name) => funcName(name) // TODO
|
||||||
}
|
}
|
||||||
case _ => // return from another invocation
|
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
|
// the assembly variable "heap" contains a pointer to the first valid byte
|
||||||
// in the heap. Make sure to update its value accordingly.
|
// in the heap. Make sure to update its value accordingly.
|
||||||
// TODO
|
// TODO
|
||||||
emitln(s"movq (%rip), ${loc(sp)}")
|
emitln(s"movq heap, ${loc(sp)}")
|
||||||
trans(size, sp + 1)(env)
|
trans(size, sp + 1)(env)
|
||||||
emitln(s"movq (%rip), ${loc(sp + 2)}")
|
emitln(s"shlq $$3, ${loc(sp + 1)}")
|
||||||
emitln(s"movq (${loc(sp + 2)}, ${loc(sp + 1)}, 8), ${loc(sp + 2)}")
|
emitln(s"addq ${loc(sp + 1)}, heap")
|
||||||
emitln(s"movq ${loc(sp + 2)}, %rip")
|
|
||||||
case _ => BUG(s"don't know how to implement $exp")
|
case _ => BUG(s"don't know how to implement $exp")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ OPTION: intStack""")
|
|||||||
} else {
|
} else {
|
||||||
args(0)
|
args(0)
|
||||||
}
|
}
|
||||||
|
//val src = "var x = 2; while (x<777) {x = x + 2;putchar(x)};x"
|
||||||
println("============ SRC CODE ============")
|
println("============ SRC CODE ============")
|
||||||
println(src)
|
println(src)
|
||||||
println("==================================\n")
|
println("==================================\n")
|
||||||
|
|||||||
@@ -520,7 +520,10 @@ class BaseParser(in: Scanner) extends Parser(in) {
|
|||||||
val res = parseExpression
|
val res = parseExpression
|
||||||
accept('}')
|
accept('}')
|
||||||
res
|
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)) {
|
def parseUAtom: Exp = if (in.hasNext(isOperator)) {
|
||||||
@@ -579,7 +582,7 @@ class BaseParser(in: Scanner) extends Parser(in) {
|
|||||||
val body = parseExpression
|
val body = parseExpression
|
||||||
VarDec(name, tp, rhs, body).withPos(pos)
|
VarDec(name, tp, rhs, body).withPos(pos)
|
||||||
case Keyword("while") =>
|
case Keyword("while") =>
|
||||||
val pos = accept("while").pos
|
val pos = in.next().pos
|
||||||
accept('(')
|
accept('(')
|
||||||
val cond = parseSimpleExpression
|
val cond = parseSimpleExpression
|
||||||
accept(')')
|
accept(')')
|
||||||
@@ -648,7 +651,7 @@ class SyntacticSugarParser(in: Scanner) extends BaseParser(in) {
|
|||||||
suf + "$" + next
|
suf + "$" + next
|
||||||
}
|
}
|
||||||
|
|
||||||
override def parseSimpleExpression = in.peek match { // !!!
|
override def parseSimpleExpression = in.peek match {
|
||||||
case Keyword("if") =>
|
case Keyword("if") =>
|
||||||
val pos = in.next().pos
|
val pos = in.next().pos
|
||||||
accept('(')
|
accept('(')
|
||||||
@@ -667,17 +670,11 @@ class SyntacticSugarParser(in: Scanner) extends BaseParser(in) {
|
|||||||
|
|
||||||
override def parseExpression = {
|
override def parseExpression = {
|
||||||
// NOTE: parse expression terminates when it parse a simples expression.
|
// NOTE: parse expression terminates when it parse a simples expression.
|
||||||
// syntax sugar allows to have an other expression after it. !!!
|
// syntax sugar allows to have an other expression after it.
|
||||||
var res = in.peek match {
|
var res = super.parseExpression
|
||||||
case Keyword("val") | Keyword("var") | Keyword("while") =>
|
if(in.hasNext(_ match {case Delim(';') => true; case _ => false})){
|
||||||
super.parseExpression
|
accept(';')
|
||||||
case _ =>
|
res = Let(freshName(), UnknownType, res, parseExpression).withPos(res.pos)
|
||||||
var simp = parseSimpleExpression
|
|
||||||
if(isNewLine(in.peek)) {
|
|
||||||
accept(';')
|
|
||||||
simp = Let(freshName(), UnknownType, simp, parseExpression).withPos(simp.pos)
|
|
||||||
}
|
|
||||||
simp
|
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
@@ -764,30 +761,24 @@ class FunctionParser(in: Scanner) extends SyntacticSugarParser(in) {
|
|||||||
/*
|
/*
|
||||||
* This function parse types.
|
* This function parse types.
|
||||||
*
|
*
|
||||||
* TODO !!!
|
* TODO
|
||||||
*/
|
*/
|
||||||
override def parseType = in.peek match {
|
override def parseType = in.peek match {
|
||||||
case Delim('(') =>
|
case Delim('(') =>
|
||||||
accept('(')
|
accept('(')
|
||||||
val list = parseList[Type](parseType, ',', tok => tok match {
|
val list = parseList[Type](parseType, ',', _ match {
|
||||||
case Delim(')') => false;
|
case Delim(')') => false; case _ => true
|
||||||
case _ => true
|
|
||||||
})
|
})
|
||||||
val argList = list map { tp => ("", tp)}
|
val args = list map { tp => ("", tp)}
|
||||||
accept("=>")
|
accept("=>")
|
||||||
val rtp = parseType
|
FunType(args, parseType)
|
||||||
FunType(argList, rtp)
|
|
||||||
case _ =>
|
case _ =>
|
||||||
val typ = super.parseType
|
var ty = super.parseType
|
||||||
if(in.peek == Delim('=') && in.peek1 == Ident(">")) {
|
if(in.peek == Delim('=') && in.peek1 == Ident(">")) {
|
||||||
accept("=>")
|
accept("=>")
|
||||||
val rtp = super.parseType
|
ty = FunType(List(("", ty)), super.parseType)
|
||||||
val typList: List[(String, Type)] = List(("", typ))
|
}
|
||||||
FunType(typList, rtp)
|
ty
|
||||||
}
|
|
||||||
else {
|
|
||||||
typ
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -369,7 +369,7 @@ class SemanticAnalyzer(parser: Parser) extends Reporter with BugReporter {
|
|||||||
*/
|
*/
|
||||||
pt match {
|
pt match {
|
||||||
case UnitType | IntType | BooleanType | CharType => VarAssign(x, rhsChecked).withType(rhsChecked.tp)
|
case UnitType | IntType | BooleanType | CharType => VarAssign(x, rhsChecked).withType(rhsChecked.tp)
|
||||||
case _ => exp.withType(UnknownType)
|
case _ => exp.withType(UnitType)
|
||||||
}
|
}
|
||||||
case While(cond, lbody, body) =>
|
case While(cond, lbody, body) =>
|
||||||
val condChecked = typeCheck(cond, BooleanType)(env)
|
val condChecked = typeCheck(cond, BooleanType)(env)
|
||||||
@@ -389,9 +389,9 @@ class SemanticAnalyzer(parser: Parser) extends Reporter with BugReporter {
|
|||||||
|
|
||||||
case LetRec(funs, body) =>
|
case LetRec(funs, body) =>
|
||||||
// TODO modify to handle general case
|
// TODO modify to handle general case
|
||||||
val _env = env.withVals(funs.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(_, _, rtp, _) => typeCheck(f, rtp)(_env) }
|
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, _, rtp, _) => (name, rtp)}))
|
val bodyChecked = typeCheck(body, pt)( env.withVals(funsChecked map {case FunDef(name, args, rtp, _) => (name, funType(args, rtp))}))
|
||||||
LetRec(funsChecked, bodyChecked).withType(bodyChecked.tp)
|
LetRec(funsChecked, bodyChecked).withType(bodyChecked.tp)
|
||||||
|
|
||||||
case App(fun, args) =>
|
case App(fun, args) =>
|
||||||
|
|||||||
@@ -38,4 +38,20 @@ class CompilerTest extends TimedSuite {
|
|||||||
testCompiler(LetRec(Nil, Prim("-", List(Lit(10), Lit(2)))), 8)
|
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))
|
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") {
|
test("ParseOptionalType") {
|
||||||
testBaseParser("val x = 1; 2", Let("x", UnknownType, Lit(1), Lit(2)))
|
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