diff -r 3b1136fb6bee -r f0696713177b progs/fun/fun.sc --- a/progs/fun/fun.sc Sat Oct 24 13:02:18 2020 +0100 +++ b/progs/fun/fun.sc Sun Oct 25 01:25:01 2020 +0000 @@ -3,32 +3,19 @@ // // call with // -// amm fun.sc +// amm fun.sc main defs.fun +// +// amm fun.sc main fact.fun // -// this will print out the JVM instructions for two +// or +// amm fun.sc test +// +// the latter will print out the JVM instructions for two // factorial functions - -// abstract syntax trees -abstract class Exp -abstract class BExp -abstract class Decl - -// functions and declarations -case class Def(name: String, args: List[String], body: Exp) extends Decl -case class Main(e: Exp) extends Decl +import $file.fun_tokens, fun_tokens._ +import $file.fun_parser, fun_parser._ -// expressions -case class Call(name: String, args: List[Exp]) extends Exp -case class If(a: BExp, e1: Exp, e2: Exp) extends Exp -case class Write(e: Exp) extends Exp -case class Var(s: String) extends Exp -case class Num(i: Int) extends Exp -case class Aop(o: String, a1: Exp, a2: Exp) extends Exp -case class Sequ(e1: Exp, e2: Exp) extends Exp - -// boolean expressions -case class Bop(o: String, a1: Exp, a2: Exp) extends BExp // calculating the maximal needed stack size def max_stack_exp(e: Exp): Int = e match { @@ -39,8 +26,9 @@ case Var(_) => 1 case Num(_) => 1 case Aop(_, a1, a2) => max_stack_exp(a1) + max_stack_exp(a2) - case Sequ(e1, e2) => List(max_stack_exp(e1), max_stack_exp(e2)).max + case Sequence(e1, e2) => List(max_stack_exp(e1), max_stack_exp(e2)).max } + def max_stack_bexp(e: BExp): Int = e match { case Bop(_, a1, a2) => max_stack_exp(a1) + max_stack_exp(a2) } @@ -112,7 +100,7 @@ args.map(a => compile_exp(a, env)).mkString ++ i"invokestatic XXX/XXX/$name($is)I" } - case Sequ(a1, a2) => { + case Sequence(a1, a2) => { compile_exp(a1, env) ++ i"pop" ++ compile_exp(a2, env) } case Write(a1) => { @@ -192,10 +180,20 @@ Call("facT",List(Aop("-",Var("n"),Num(1)), Aop("*",Var("n"),Var("acc")))))), - Main(Sequ(Write(Call("fact",List(Num(10)))), + Main(Sequence(Write(Call("fact",List(Num(10)))), Write(Call("facT",List(Num(10), Num(1))))))) // prints out the JVM instructions @main def test() = println(compile(test_prog, "fact")) + + +@main +def main(fname: String) = { + val path = os.pwd / fname + val class_name = fname.stripSuffix("." ++ path.ext) + val tks = tokenise(os.read(path)) + val ast = parse_tks(tks) + println(compile(ast, class_name)) +}