Compiler/AST interpreter: Difference between revisions
Content added Content deleted
(Added java version) |
No edit summary |
||
Line 2,486: | Line 2,486: | ||
</pre> |
</pre> |
||
</b> |
</b> |
||
=={{header|Scala}}== |
|||
The complete implementation for the compiler tasks can be found in a GitHub repository at [https://github.com/edadma/rosettacodeCompiler github.com/edadma/rosettacodeCompiler] which includes full unit testing for the samples given in [[Compiler/Sample programs]]. |
|||
The following code implements as AST interpreter for the output of the [http://rosettacode.org/wiki/Compiler/syntax_analyzer#Scala parser] |
|||
<lang scala> |
|||
package xyz.hyperreal.rosettacodeCompiler |
|||
import scala.collection.mutable |
|||
import scala.io.Source |
|||
object ASTInterpreter { |
|||
def fromStdin = fromSource(Source.stdin) |
|||
def fromString(src: String) = fromSource(Source.fromString(src)) |
|||
def fromSource(s: Source) = { |
|||
val lines = s.getLines |
|||
def load: Node = |
|||
if (!lines.hasNext) |
|||
TerminalNode |
|||
else |
|||
lines.next.split(" +", 2) match { |
|||
case Array(name, value) => LeafNode(name, value) |
|||
case Array(";") => TerminalNode |
|||
case Array(name) => BranchNode(name, load, load) |
|||
} |
|||
val vars = new mutable.HashMap[String, Any] |
|||
def interpInt(n: Node) = interp(n).asInstanceOf[Int] |
|||
def interpBoolean(n: Node) = interp(n).asInstanceOf[Boolean] |
|||
def interp(n: Node): Any = |
|||
n match { |
|||
case TerminalNode => null |
|||
case LeafNode("Identifier", name) => |
|||
vars get name match { |
|||
case None => |
|||
vars(name) = 0 |
|||
0 |
|||
case Some(v) => v |
|||
} |
|||
case LeafNode("Integer", "'\\n'") => '\n'.toInt |
|||
case LeafNode("Integer", "'\\\\'") => '\\'.toInt |
|||
case LeafNode("Integer", value: String) if value startsWith "'" => value(1).toInt |
|||
case LeafNode("Integer", value: String) => value.toInt |
|||
case LeafNode("String", value: String) => unescape(value.substring(1, value.length - 1)) |
|||
case BranchNode("Assign", LeafNode(_, name), exp) => vars(name) = interp(exp) |
|||
case BranchNode("Sequence", l, r) => interp(l); interp(r) |
|||
case BranchNode("Prts" | "Prti", a, _) => print(interp(a)) |
|||
case BranchNode("Prtc", a, _) => print(interpInt(a).toChar) |
|||
case BranchNode("Add", l, r) => interpInt(l) + interpInt(r) |
|||
case BranchNode("Subtract", l, r) => interpInt(l) - interpInt(r) |
|||
case BranchNode("Multiply", l, r) => interpInt(l) * interpInt(r) |
|||
case BranchNode("Divide", l, r) => interpInt(l) / interpInt(r) |
|||
case BranchNode("Mod", l, r) => interpInt(l) % interpInt(r) |
|||
case BranchNode("Negate", a, _) => -interpInt(a) |
|||
case BranchNode("Less", l, r) => interpInt(l) < interpInt(r) |
|||
case BranchNode("LessEqual", l, r) => interpInt(l) <= interpInt(r) |
|||
case BranchNode("Greater", l, r) => interpInt(l) > interpInt(r) |
|||
case BranchNode("GreaterEqual", l, r) => interpInt(l) >= interpInt(r) |
|||
case BranchNode("Equal", l, r) => interpInt(l) == interpInt(r) |
|||
case BranchNode("NotEqual", l, r) => interpInt(l) != interpInt(r) |
|||
case BranchNode("And", l, r) => interpBoolean(l) && interpBoolean(r) |
|||
case BranchNode("Or", l, r) => interpBoolean(l) || interpBoolean(r) |
|||
case BranchNode("Not", a, _) => !interpBoolean(a) |
|||
case BranchNode("While", l, r) => while (interpBoolean(l)) interp(r) |
|||
case BranchNode("If", cond, BranchNode("If", yes, no)) => if (interpBoolean(cond)) interp(yes) else interp(no) |
|||
} |
|||
interp(load) |
|||
} |
|||
abstract class Node |
|||
case class BranchNode(name: String, left: Node, right: Node) extends Node |
|||
case class LeafNode(name: String, value: String) extends Node |
|||
case object TerminalNode extends Node |
|||
} |
|||
</lang> |
|||
=={{header|Scheme}}== |
=={{header|Scheme}}== |