Commit 730f7455 authored by Miro Knejp's avatar Miro Knejp

AST representation of external types

parent 18b37727
...@@ -37,7 +37,14 @@ case class TypeParam(ident: Ident) ...@@ -37,7 +37,14 @@ case class TypeParam(ident: Ident)
case class Doc(lines: Seq[String]) case class Doc(lines: Seq[String])
case class TypeDecl(ident: Ident, params: Seq[TypeParam], body: TypeDef, doc: Doc, origin: String) sealed abstract class TypeDecl {
val ident: Ident
val params: Seq[TypeParam]
val body: TypeDef
val origin: String
}
case class InternTypeDecl(override val ident: Ident, override val params: Seq[TypeParam], override val body: TypeDef, doc: Doc, override val origin: String) extends TypeDecl
case class ExternTypeDecl(override val ident: Ident, override val params: Seq[TypeParam], override val body: TypeDef, properties: Map[String, Any], override val origin: String) extends TypeDecl
case class Ext(java: Boolean, cpp: Boolean, objc: Boolean) { case class Ext(java: Boolean, cpp: Boolean, objc: Boolean) {
def any(): Boolean = { def any(): Boolean = {
......
...@@ -298,8 +298,7 @@ abstract class Generator(spec: Spec) ...@@ -298,8 +298,7 @@ abstract class Generator(spec: Spec)
} }
def generate(idl: Seq[TypeDecl]) { def generate(idl: Seq[TypeDecl]) {
for (td <- idl) { for (td <- idl.collect { case itd: InternTypeDecl => itd }) td.body match {
td.body match {
case e: Enum => case e: Enum =>
assert(td.params.isEmpty) assert(td.params.isEmpty)
generateEnum(td.origin, td.ident, td.doc, e) generateEnum(td.origin, td.ident, td.doc, e)
...@@ -307,7 +306,6 @@ abstract class Generator(spec: Spec) ...@@ -307,7 +306,6 @@ abstract class Generator(spec: Spec)
case i: Interface => generateInterface(td.origin, td.ident, td.doc, td.params, i) case i: Interface => generateInterface(td.origin, td.ident, td.doc, td.params, i)
} }
} }
}
def generateEnum(origin: String, ident: Ident, doc: Doc, e: Enum) def generateEnum(origin: String, ident: Ident, doc: Doc, e: Enum)
def generateRecord(origin: String, ident: Ident, doc: Doc, params: Seq[TypeParam], r: Record) def generateRecord(origin: String, ident: Ident, doc: Doc, params: Seq[TypeParam], r: Record)
......
...@@ -51,7 +51,7 @@ private object IdlParser extends RegexParsers { ...@@ -51,7 +51,7 @@ private object IdlParser extends RegexParsers {
def externDirective = "extern".r def externDirective = "extern".r
def typeDecl(origin: String): Parser[TypeDecl] = doc ~ ident ~ typeList(ident ^^ TypeParam) ~ "=" ~ typeDef ^^ { def typeDecl(origin: String): Parser[TypeDecl] = doc ~ ident ~ typeList(ident ^^ TypeParam) ~ "=" ~ typeDef ^^ {
case doc~ident~typeParams~_~body => TypeDecl(ident, typeParams, body, doc, origin) case doc~ident~typeParams~_~body => InternTypeDecl(ident, typeParams, body, doc, origin)
} }
def ext(default: Ext) = (rep1("+" ~> ident) >> checkExts) | success(default) def ext(default: Ext) = (rep1("+" ~> ident) >> checkExts) | success(default)
......
...@@ -42,7 +42,7 @@ def resolve(metas: Scope, idl: Seq[TypeDecl]): Option[Error] = { ...@@ -42,7 +42,7 @@ def resolve(metas: Scope, idl: Seq[TypeDecl]): Option[Error] = {
for (typeDecl <- idl) { for (typeDecl <- idl) {
topLevelDupeChecker.check(typeDecl.ident) topLevelDupeChecker.check(typeDecl.ident)
val defType = typeDecl.body match { def defType = typeDecl.body match {
case e: Enum => case e: Enum =>
if (!typeDecl.params.isEmpty) { if (!typeDecl.params.isEmpty) {
throw Error(typeDecl.ident.loc, "enums can't have type parameters").toException throw Error(typeDecl.ident.loc, "enums can't have type parameters").toException
...@@ -51,8 +51,10 @@ def resolve(metas: Scope, idl: Seq[TypeDecl]): Option[Error] = { ...@@ -51,8 +51,10 @@ def resolve(metas: Scope, idl: Seq[TypeDecl]): Option[Error] = {
case r: Record => DRecord case r: Record => DRecord
case i: Interface => DInterface case i: Interface => DInterface
} }
val mdef = MDef(typeDecl.ident.name, typeDecl.params.length, defType, typeDecl.body) topScope = topScope.updated(typeDecl.ident.name, typeDecl match {
topScope = topScope.updated(typeDecl.ident.name, mdef) case td: InternTypeDecl => MDef(typeDecl.ident.name, typeDecl.params.length, defType, typeDecl.body)
case td: ExternTypeDecl => throw new AssertionError("not implemented")
})
} }
// Resolve everything // Resolve everything
...@@ -201,6 +203,7 @@ private def constTypeCheck(ty: MExpr, value: Any, resolvedConsts: Seq[Const]) { ...@@ -201,6 +203,7 @@ private def constTypeCheck(ty: MExpr, value: Any, resolvedConsts: Seq[Const]) {
throw new AssertionError(s"Const type mismatch: enum ${d.name} does not have option ${opt.name}") throw new AssertionError(s"Const type mismatch: enum ${d.name} does not have option ${opt.name}")
} }
} }
case e: MExtern => throw new AssertionError("Extern type not allowed for constant")
case _ => throw new AssertionError("Const type cannot be resolved") case _ => throw new AssertionError("Const type cannot be resolved")
} }
} }
...@@ -241,6 +244,15 @@ private def resolveRecord(scope: Scope, r: Record) { ...@@ -241,6 +244,15 @@ private def resolveRecord(scope: Scope, r: Record) {
throw new Error(f.ident.loc, s"Some deriving required is not implemented in record ${f.ident.name}").toException throw new Error(f.ident.loc, s"Some deriving required is not implemented in record ${f.ident.name}").toException
case DEnum => case DEnum =>
} }
case e: MExtern => e.defType match {
case DInterface =>
throw new Error(f.ident.loc, "Interface reference cannot live in a record").toException
case DRecord =>
val record = e.body.asInstanceOf[Record]
if (!r.derivingTypes.subsetOf(record.derivingTypes))
throw new Error(f.ident.loc, s"Some deriving required is not implemented in record ${f.ident.name}").toException
case DEnum =>
}
case _ => throw new AssertionError("Type cannot be resolved") case _ => throw new AssertionError("Type cannot be resolved")
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment