diff --git a/labs/amy_specification.pdf b/labs/amy_specification.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9f2d4dc7595f6d88a28152ef197c7f664f4e3d5f Binary files /dev/null and b/labs/amy_specification.pdf differ diff --git a/labs/labs01_material/SymbolicTreeModule.scala b/labs/labs01_material/SymbolicTreeModule.scala new file mode 100755 index 0000000000000000000000000000000000000000..c59943667302afa485cb319606f735eb0703ae52 --- /dev/null +++ b/labs/labs01_material/SymbolicTreeModule.scala @@ -0,0 +1,91 @@ +package amyc.ast + +import amyc.utils.Positioned + +// Definitions of symbolic Amy syntax trees +trait TreeModule { + // Common ancestor for all trees + trait Tree extends Positioned + + // Expressions + trait Expr extends Tree + + // Variables + case class Variable(name: Identifier) extends Expr + + // Literals + trait Literal[+T] extends Expr { val value: T } + case class IntLiteral(value: Int) extends Literal[Int] + case class BooleanLiteral(value: Boolean) extends Literal[Boolean] + case class StringLiteral(value: String) extends Literal[String] + case class UnitLiteral() extends Literal[Unit] { val value: Unit = () } + + // Binary operators + case class Plus(lhs: Expr, rhs: Expr) extends Expr + case class Minus(lhs: Expr, rhs: Expr) extends Expr + case class Times(lhs: Expr, rhs: Expr) extends Expr + case class Div(lhs: Expr, rhs: Expr) extends Expr + case class Mod(lhs: Expr, rhs: Expr) extends Expr + case class LessThan(lhs: Expr, rhs: Expr) extends Expr + case class LessEquals(lhs: Expr, rhs: Expr) extends Expr + case class And(lhs: Expr, rhs: Expr) extends Expr + case class Or(lhs: Expr, rhs: Expr) extends Expr + case class Equals(lhs: Expr, rhs: Expr) extends Expr + case class Concat(lhs: Expr, rhs: Expr) extends Expr + + // Unary operators + case class Not(e: Expr) extends Expr + case class Neg(e: Expr) extends Expr + + // Function/ type constructor call + case class Call(qname: Identifier, args: List[Expr]) extends Expr + // The ; operator + case class Sequence(e1: Expr, e2: Expr) extends Expr + // Local variable definition + case class Let(df: ParamDef, value: Expr, body: Expr) extends Expr + // If-then-else + case class Ite(cond: Expr, thenn: Expr, elze: Expr) extends Expr + // Pattern matching + case class Match(scrut: Expr, cases: List[MatchCase]) extends Expr { + require(cases.nonEmpty) + } + // Represents a computational error; prints its message, then exits + case class Error(msg: Expr) extends Expr + + // Cases and patterns for Match expressions + case class MatchCase(pat: Pattern, expr: Expr) extends Tree + + abstract class Pattern extends Tree + case class WildcardPattern() extends Pattern // _ + case class IdPattern(name: Identifier) extends Pattern // x + case class LiteralPattern[+T](lit: Literal[T]) extends Pattern // 42, true + case class CaseClassPattern(constr: Identifier, args: List[Pattern]) extends Pattern // C(arg1, arg2) + + // Definitions + trait Definition extends Tree { val name: Identifier } + case class ModuleDef(name: Identifier, defs: List[ClassOrFunDef], optExpr: Option[Expr]) extends Definition + trait ClassOrFunDef extends Definition + case class FunDef(name: Identifier, params: List[ParamDef], retType: TypeTree, body: Expr) extends ClassOrFunDef { + def paramNames = params.map(_.name) + } + case class AbstractClassDef(name: Identifier) extends ClassOrFunDef + case class CaseClassDef(name: Identifier, fields: List[TypeTree], parent: Identifier) extends ClassOrFunDef + case class ParamDef(name: Identifier, tpe: TypeTree) extends Definition + + // Types + trait Type + case object IntType extends Type + case object BooleanType extends Type + case object StringType extends Type + case object UnitType extends Type + case class ClassType(qname: Identifier) extends Type + + // A wrapper for types that is also a Tree (i.e. has a position) + case class TypeTree(tpe: Type) extends Tree + + // All is wrapped in a program + case class Program(modules: List[ModuleDef]) extends Tree +} + +// Identifiers represent unique names in Amy +class Identifier private(val name: String) diff --git a/labs/labs01_material/SymbolicTreeModule.scala~ b/labs/labs01_material/SymbolicTreeModule.scala~ new file mode 100755 index 0000000000000000000000000000000000000000..c59943667302afa485cb319606f735eb0703ae52 --- /dev/null +++ b/labs/labs01_material/SymbolicTreeModule.scala~ @@ -0,0 +1,91 @@ +package amyc.ast + +import amyc.utils.Positioned + +// Definitions of symbolic Amy syntax trees +trait TreeModule { + // Common ancestor for all trees + trait Tree extends Positioned + + // Expressions + trait Expr extends Tree + + // Variables + case class Variable(name: Identifier) extends Expr + + // Literals + trait Literal[+T] extends Expr { val value: T } + case class IntLiteral(value: Int) extends Literal[Int] + case class BooleanLiteral(value: Boolean) extends Literal[Boolean] + case class StringLiteral(value: String) extends Literal[String] + case class UnitLiteral() extends Literal[Unit] { val value: Unit = () } + + // Binary operators + case class Plus(lhs: Expr, rhs: Expr) extends Expr + case class Minus(lhs: Expr, rhs: Expr) extends Expr + case class Times(lhs: Expr, rhs: Expr) extends Expr + case class Div(lhs: Expr, rhs: Expr) extends Expr + case class Mod(lhs: Expr, rhs: Expr) extends Expr + case class LessThan(lhs: Expr, rhs: Expr) extends Expr + case class LessEquals(lhs: Expr, rhs: Expr) extends Expr + case class And(lhs: Expr, rhs: Expr) extends Expr + case class Or(lhs: Expr, rhs: Expr) extends Expr + case class Equals(lhs: Expr, rhs: Expr) extends Expr + case class Concat(lhs: Expr, rhs: Expr) extends Expr + + // Unary operators + case class Not(e: Expr) extends Expr + case class Neg(e: Expr) extends Expr + + // Function/ type constructor call + case class Call(qname: Identifier, args: List[Expr]) extends Expr + // The ; operator + case class Sequence(e1: Expr, e2: Expr) extends Expr + // Local variable definition + case class Let(df: ParamDef, value: Expr, body: Expr) extends Expr + // If-then-else + case class Ite(cond: Expr, thenn: Expr, elze: Expr) extends Expr + // Pattern matching + case class Match(scrut: Expr, cases: List[MatchCase]) extends Expr { + require(cases.nonEmpty) + } + // Represents a computational error; prints its message, then exits + case class Error(msg: Expr) extends Expr + + // Cases and patterns for Match expressions + case class MatchCase(pat: Pattern, expr: Expr) extends Tree + + abstract class Pattern extends Tree + case class WildcardPattern() extends Pattern // _ + case class IdPattern(name: Identifier) extends Pattern // x + case class LiteralPattern[+T](lit: Literal[T]) extends Pattern // 42, true + case class CaseClassPattern(constr: Identifier, args: List[Pattern]) extends Pattern // C(arg1, arg2) + + // Definitions + trait Definition extends Tree { val name: Identifier } + case class ModuleDef(name: Identifier, defs: List[ClassOrFunDef], optExpr: Option[Expr]) extends Definition + trait ClassOrFunDef extends Definition + case class FunDef(name: Identifier, params: List[ParamDef], retType: TypeTree, body: Expr) extends ClassOrFunDef { + def paramNames = params.map(_.name) + } + case class AbstractClassDef(name: Identifier) extends ClassOrFunDef + case class CaseClassDef(name: Identifier, fields: List[TypeTree], parent: Identifier) extends ClassOrFunDef + case class ParamDef(name: Identifier, tpe: TypeTree) extends Definition + + // Types + trait Type + case object IntType extends Type + case object BooleanType extends Type + case object StringType extends Type + case object UnitType extends Type + case class ClassType(qname: Identifier) extends Type + + // A wrapper for types that is also a Tree (i.e. has a position) + case class TypeTree(tpe: Type) extends Tree + + // All is wrapped in a program + case class Program(modules: List[ModuleDef]) extends Tree +} + +// Identifiers represent unique names in Amy +class Identifier private(val name: String)