PageRenderTime 59ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/src/orc/compile/translate/Translator.scala

https://github.com/laurenyew/cOrcS
Scala | 469 lines | 356 code | 59 blank | 54 comment | 18 complexity | 8fa38368b5020bf30a95cfcdbee045aa MD5 | raw file
Possible License(s): BSD-3-Clause
  1. //
  2. // Translator.scala -- Scala object Translator
  3. // Project OrcScala
  4. //
  5. // $Id: Translator.scala 3099 2012-07-21 02:33:18Z laurenyew $
  6. //
  7. // Created by dkitchin on May 27, 2010.
  8. //
  9. // Copyright (c) 2011 The University of Texas at Austin. All rights reserved.
  10. //
  11. // Use and redistribution of this file is governed by the license terms in
  12. // the LICENSE file found in the project's top-level directory and also found at
  13. // URL: http://orc.csres.utexas.edu/license.shtml .
  14. //
  15. package orc.compile.translate
  16. import orc.ast.ext
  17. import orc.ast.oil._
  18. import orc.ast.oil.named._
  19. import orc.ast.oil.named.Conversions._
  20. import orc.compile.translate.ClassForms._
  21. import orc.compile.translate.PrimitiveForms._
  22. import orc.error.OrcException
  23. import orc.error.OrcExceptionExtension._
  24. import orc.error.compiletime._
  25. import orc.lib.builtin
  26. import orc.values.{ Signal, Field }
  27. import orc.values.sites.{ JavaSiteForm, OrcSiteForm }
  28. import scala.collection.mutable
  29. import scala.collection.immutable._
  30. class Translator(val reportProblem: CompilationException with ContinuableSeverity => Unit) {
  31. /** Translate an extended AST to a named OIL AST.
  32. */
  33. def translate(extendedAST: ext.Expression): named.Expression = {
  34. val rootContext: Map[String, Argument] = HashMap.empty withDefault { UnboundVar(_) }
  35. val rootTypeContext: Map[String, Type] = HashMap.empty withDefault { UnboundTypevar(_) }
  36. convert(extendedAST)(rootContext, rootTypeContext)
  37. }
  38. /** Convert an extended AST expression to a named OIL expression.
  39. */
  40. def convert(e: ext.Expression)(implicit context: Map[String, Argument], typecontext: Map[String, Type]): Expression = {
  41. e -> {
  42. case ext.Stop() => Stop()
  43. case ext.Constant(c) => Constant(c)
  44. case ext.Variable(x) => context(x)
  45. case ext.TupleExpr(es) => unfold(es map convert, makeTuple)
  46. //SL Expression to Named. convert from extended expr to named expr
  47. case ext.SecurityLevelExpression(e,l) => HasSecurityLevel(convert(e),l)
  48. case ext.ListExpr(es) => unfold(es map convert, makeList)
  49. case ext.RecordExpr(es) => {
  50. val seen = new scala.collection.mutable.HashSet[String]()
  51. val tuples = es map
  52. {
  53. case (s, e) => {
  54. if (seen contains s) { reportProblem(DuplicateKeyException(s) at e) } else { seen += s }
  55. val f = Constant(Field(s))
  56. unfold(List(f, convert(e)), makeTuple)
  57. }
  58. }
  59. unfold(tuples, makeRecord)
  60. }
  61. case ext.Call(target, gs) => {
  62. var expr = convert(target)
  63. for (g <- gs) {
  64. expr = unfold(List(expr), { case List(m) => convertArgumentGroup(m, g) ; case _ => throw new AssertionError("Translator internal failure (convert Call arg group match error)")})
  65. }
  66. expr
  67. }
  68. case ext.PrefixOperator(opName, exp) => {
  69. val actualOpName = if (opName == "-") "0-" else opName
  70. val op = context(actualOpName)
  71. unfold(List(exp) map convert, { Call(op, _, None) })
  72. }
  73. case ext.InfixOperator(l, opName, r) => {
  74. val op = context(opName)
  75. unfold(List(l, r) map convert, { Call(op, _, None) })
  76. }
  77. case ext.Sequential(l, None, r) => convert(l) >> convert(r)
  78. case ext.Sequential(l, Some(ext.VariablePattern(name)), r) => {
  79. val x = new BoundVar(Some(name))
  80. val newl = convert(l)
  81. val newr = convert(r)(context + ((name, x)), typecontext)
  82. newl > x > newr
  83. }
  84. case ext.Sequential(l, Some(p), r) => {
  85. val x = new BoundVar()
  86. val (source, dcontext, target) = convertPattern(p, x)
  87. val newl = convert(l)
  88. val newr = convert(r)(context ++ dcontext, typecontext)
  89. source(newl) > x > target(newr)
  90. }
  91. case ext.Pruning(l, None, r) => convert(l) << convert(r)
  92. case ext.Pruning(l, Some(ext.VariablePattern(name)), r) => {
  93. val x = new BoundVar(Some(name))
  94. val newl = convert(l)(context + ((name, x)), typecontext)
  95. val newr = convert(r)
  96. newl < x < newr
  97. }
  98. case ext.Pruning(l, Some(p), r) => {
  99. val x = new BoundVar()
  100. val (source, dcontext, target) = convertPattern(p, x)
  101. val newl = convert(l)(context ++ dcontext, typecontext)
  102. val newr = convert(r)
  103. target(newl) < x < source(newr)
  104. }
  105. case ext.Parallel(l, r) => convert(l) || convert(r)
  106. case ext.Otherwise(l, r) => convert(l) ow convert(r)
  107. case lambda: ext.Lambda => {
  108. val lambdaName = new BoundVar()
  109. val newdef = AggregateDef(lambda)(this).convert(lambdaName, context, typecontext)
  110. DeclareDefs(List(newdef), lambdaName)
  111. }
  112. case ext.DefClassBody(b) => {
  113. var capThunk = ext.Lambda(None, Nil, None, None, makeClassBody(b, reportProblem))
  114. convert(ext.Call(
  115. ext.Call(ext.Constant(builtin.MakeSite), List(ext.Args(None, List(capThunk)))), List(ext.Args(None, Nil))))
  116. }
  117. case ext.Conditional(ifE, thenE, elseE) => {
  118. makeConditional(convert(ifE), convert(thenE), convert(elseE))
  119. }
  120. case ext.DefGroup(defs, body) => {
  121. val (newdefs, dcontext) = convertDefs(defs)
  122. val newbody = convert(body)(context ++ dcontext, typecontext)
  123. DeclareDefs(newdefs, newbody)
  124. }
  125. case ext.Declare(ext.Val(p, f), body) => {
  126. convert(ext.Pruning(body, Some(p), f))
  127. }
  128. case ext.Declare(ext.SiteImport(name, sitename), body) => {
  129. try {
  130. val site = Constant(OrcSiteForm.resolve(sitename))
  131. convert(body)(context + { (name, site) }, typecontext)
  132. } catch {
  133. case oe: OrcException => throw oe at e
  134. }
  135. }
  136. case ext.Declare(ext.ClassImport(name, classname), body) => {
  137. try {
  138. val u = new BoundTypevar(Some(name))
  139. val site = Constant(JavaSiteForm.resolve(classname))
  140. val newbody = convert(body)(context + { (name, site) }, typecontext + { (name, u) })
  141. DeclareType(u, ClassType(classname), newbody)
  142. } catch {
  143. case oe: OrcException => throw oe at e
  144. }
  145. }
  146. case ext.Declare(ext.Include(_, decls), body) => convert((decls foldRight body) { ext.Declare })
  147. case ext.Declare(ext.TypeImport(name, classname), body) => {
  148. val u = new BoundTypevar(Some(name))
  149. val newbody = convert(body)(context, typecontext + { (name, u) })
  150. DeclareType(u, ImportedType(classname), newbody)
  151. }
  152. //Declare SL from Extended translate to Named
  153. //body is the expression we convert to named expression
  154. case ext.Declare(ext.SecurityLevelDeclaration(name,parents,children), body) => {
  155. DeclareSecurityLevel(name,parents,children, convert(body))
  156. }
  157. case ext.Declare(decl @ ext.TypeAlias(name, typeformals, t), body) => {
  158. val u = new BoundTypevar(Some(name))
  159. val newtype =
  160. typeformals match {
  161. case Nil => convertType(t)
  162. case _ => {
  163. val (newTypeFormals, dtypecontext) = convertTypeFormals(typeformals, decl)
  164. val enclosedType = convertType(t)(typecontext ++ dtypecontext)
  165. TypeAbstraction(newTypeFormals, enclosedType)
  166. }
  167. }
  168. val newbody = convert(body)(context, typecontext + { (name, u) })
  169. DeclareType(u, newtype, newbody)
  170. }
  171. case ext.Declare(decl @ ext.Datatype(name, typeformals, constructors), body) => {
  172. val d = new BoundTypevar(Some(name))
  173. val variantType = {
  174. val selfVar = new BoundTypevar(Some(name))
  175. val (newTypeFormals, dtypecontext) = convertTypeFormals(typeformals, decl)
  176. val newtypecontext = typecontext ++ dtypecontext + { (name, selfVar) }
  177. val variants =
  178. for (ext.Constructor(name, types) <- constructors) yield {
  179. val newtypes = types map {
  180. case Some(t) => convertType(t)(newtypecontext)
  181. case None => Top()
  182. }
  183. (name, newtypes)
  184. }
  185. VariantType(selfVar, newTypeFormals, variants)
  186. }
  187. val names = constructors map { _.name }
  188. val p = ext.TuplePattern(names map { ext.VariablePattern(_) })
  189. val x = new BoundVar()
  190. val (source, dcontext, target) = convertPattern(p, x)
  191. val newbody = convert(body)(context ++ dcontext, typecontext + { (name, d) })
  192. val makeSites = makeDatatype(d, typeformals.size, constructors, this)
  193. DeclareType(d, variantType, target(newbody) < x < source(makeSites))
  194. }
  195. case ext.Declare(decl, _) => throw (MalformedExpression("Invalid declaration form") at decl)
  196. case ext.TypeAscription(body, t) => HasType(convert(body), convertType(t))
  197. case ext.TypeAssertion(body, t) => HasType(convert(body), AssertedType(convertType(t)))
  198. case ext.Hole => Hole(context, typecontext)
  199. }
  200. }
  201. def convertArgumentGroup(target: Argument, ag: ext.ArgumentGroup)(implicit context: Map[String, Argument], typecontext: Map[String, Type]): Expression = {
  202. ag match {
  203. case ext.Args(typeargs, args) => {
  204. val newtypeargs = typeargs map { _ map convertType }
  205. unfold(args map convert, { Call(target, _, newtypeargs) })
  206. }
  207. case ext.FieldAccess(field) => {
  208. Call(target, List(Constant(Field(field))), None)
  209. }
  210. case ext.Dereference => {
  211. Call(context("?"), List(target), None)
  212. }
  213. }
  214. }
  215. /** Convert a list of extended AST def declarations to:
  216. *
  217. * a list of named OIL definitions
  218. * and
  219. * a mapping from their string names to their new bound names
  220. */
  221. def convertDefs(defs: List[ext.DefDeclaration])(implicit context: Map[String, Argument], typecontext: Map[String, Type]): (List[Def], Map[String, BoundVar]) = {
  222. var defsMap: Map[String, AggregateDef] = HashMap.empty.withDefaultValue(AggregateDef.empty(this))
  223. for (d <- defs; n = d.name) {
  224. defsMap = defsMap + { (n, defsMap(n) + d) }
  225. }
  226. defsMap.values foreach { _.ClassCheck }
  227. // we generate these names beforehand since defs can be bound recursively in their own bodies
  228. val namesMap: Map[String, BoundVar] = Map.empty ++ (for (name <- defsMap.keys) yield (name, new BoundVar(Some(name))))
  229. val recursiveContext = context ++ namesMap
  230. val newdefs = for ((n, d) <- defsMap) yield {
  231. d.convert(namesMap(n), recursiveContext, typecontext)
  232. }
  233. (newdefs.toList, namesMap)
  234. }
  235. /** Convert an extended AST type to a named OIL type.
  236. */
  237. def convertType(t: ext.Type)(implicit typecontext: Map[String, Type]): named.Type = {
  238. t -> {
  239. case ext.TypeVariable(name) => typecontext(name)
  240. case ext.TupleType(ts) => TupleType(ts map convertType)
  241. case ext.RecordType(entries) => {
  242. val newEntries = (HashMap.empty ++ entries) mapValues convertType
  243. RecordType(newEntries)
  244. }
  245. case ext.TypeApplication(name, typeactuals) => {
  246. TypeApplication(typecontext(name), typeactuals map convertType)
  247. }
  248. case ext.LambdaType(typeformals, argtypes, returntype) => {
  249. val (newTypeFormals, dtypecontext) = convertTypeFormals(typeformals, t)
  250. val newtypecontext = typecontext ++ dtypecontext
  251. val newArgTypes = argtypes map { convertType(_)(newtypecontext) }
  252. val newReturnType = convertType(returntype)(newtypecontext)
  253. FunctionType(newTypeFormals, newArgTypes, newReturnType)
  254. }
  255. }
  256. }
  257. /** Convert a list of type formal names to:
  258. *
  259. * A list of bound type formal variables
  260. * and
  261. * A context mapping those names to those vars
  262. */
  263. def convertTypeFormals(typeformals: List[String], ast: orc.ast.AST): (List[BoundTypevar], Map[String, BoundTypevar]) = {
  264. var newTypeFormals: List[BoundTypevar] = Nil
  265. var formalsMap = new HashMap[String, BoundTypevar]()
  266. for (name <- typeformals.reverse) {
  267. if (formalsMap contains name) {
  268. reportProblem(DuplicateTypeFormalException(name) at ast)
  269. } else {
  270. val w = new BoundTypevar(Some(name))
  271. newTypeFormals = w :: newTypeFormals
  272. formalsMap = formalsMap + { (name, w) }
  273. }
  274. }
  275. (newTypeFormals, formalsMap)
  276. }
  277. type Conversion = Expression => Expression
  278. val id: Conversion = { e => e }
  279. /** Convert an extended AST pattern to:
  280. *
  281. * A filtering conversion for the source expression
  282. * and
  283. * A binding conversion for the target expression,
  284. * parameterized on the variable carrying the result
  285. */
  286. def convertPattern(p: ext.Pattern, bridge: BoundVar)(implicit context: Map[String, Argument], typecontext: Map[String, Type]): (Conversion, Map[String, Argument], Conversion) = {
  287. var bindingMap: mutable.Map[String, BoundVar] = new mutable.HashMap()
  288. def bind(name: String, x: BoundVar) {
  289. if (bindingMap contains name) {
  290. reportProblem(NonlinearPatternException(name) at p)
  291. } else {
  292. bindingMap += { (name, x) }
  293. }
  294. }
  295. def unravel(p: ext.Pattern, focus: BoundVar): (Conversion) = {
  296. p match {
  297. case ext.Wildcard() => {
  298. id
  299. }
  300. case ext.ConstantPattern(c) => {
  301. val b = new BoundVar();
  302. { callEq(focus, Constant(c)) > b > callIft(b) >> _ }
  303. }
  304. case ext.VariablePattern(name) => {
  305. bind(name, focus)
  306. id
  307. }
  308. case ext.TuplePattern(Nil) => {
  309. unravel(ext.ConstantPattern(Signal), focus)
  310. }
  311. case ext.TuplePattern(List(p)) => {
  312. unravel(p, focus)
  313. }
  314. case ext.TuplePattern(ps) => {
  315. /* Test that the pattern's size matches the focus tuple's size */
  316. val tuplesize = Constant(BigInt(ps.size))
  317. val sizecheck = { callTupleArityChecker(focus, tuplesize) >> _ }
  318. /* Match each element of the tuple against its corresponding pattern */
  319. var elements = id
  320. for ((p, i) <- ps.zipWithIndex) {
  321. val y = new BoundVar()
  322. val bindElement: Conversion = { makeNth(focus, i) > y > _ }
  323. elements = elements compose bindElement compose unravel(p, y)
  324. }
  325. sizecheck compose elements
  326. }
  327. case ext.ListPattern(Nil) => {
  328. { callIsNil(focus) >> _ }
  329. }
  330. case ext.ListPattern(List(p)) => {
  331. val consp = ext.ConsPattern(p, ext.ListPattern(Nil))
  332. unravel(consp, focus)
  333. }
  334. case ext.ListPattern(ps) => {
  335. val seed: ext.Pattern = ext.ListPattern(Nil)
  336. val folded = (ps foldRight seed)(ext.ConsPattern)
  337. unravel(folded, focus)
  338. }
  339. case ext.ConsPattern(ph, pt) => {
  340. val y = new BoundVar()
  341. val p = ext.TuplePattern(List(ph, pt));
  342. { callIsCons(focus) > y > _ } compose unravel(p, y)
  343. }
  344. case ext.RecordPattern(elements) => {
  345. val y = new BoundVar()
  346. val (labels, patterns) = elements.unzip
  347. val p = ext.TuplePattern(patterns);
  348. { callRecordMatcher(focus, labels) > y > _ } compose unravel(p, y)
  349. }
  350. case ext.CallPattern(name, args) => {
  351. val y = new BoundVar()
  352. val p = ext.TuplePattern(args)
  353. val C = context(name);
  354. { makeUnapply(C, focus) > y > _ } compose unravel(p, y)
  355. }
  356. case ext.AsPattern(p, name) => {
  357. bind(name, focus)
  358. unravel(p, focus)
  359. }
  360. //SL for patterns Ex:x@A = 1
  361. //unravel: turns pattern into an expression
  362. //compose: attaches SL to the expression
  363. //ascribe laces expression into _
  364. case ext.SecurityLevelPattern(p,l) => {
  365. val ascribe: Conversion = { HasSecurityLevel(_, l) }
  366. ascribe compose unravel(p, focus)
  367. }
  368. case ext.TypedPattern(p, t) => {
  369. val T = convertType(t)
  370. val ascribe: Conversion = { HasType(_, T) }
  371. ascribe compose unravel(p, focus)
  372. }
  373. }
  374. }
  375. val sourceVar = new BoundVar()
  376. val filterInto = unravel(p, sourceVar)
  377. bindingMap.values.toList.distinct match {
  378. case Nil => {
  379. /* None of the computed results are needed; the pattern had only guards, and no bindings. */
  380. val sourceConversion: Conversion =
  381. { _ > sourceVar > filterInto(Constant(Signal)) }
  382. (sourceConversion, HashMap.empty, id)
  383. }
  384. case List(neededResult) => {
  385. /* Only one result is needed */
  386. val sourceConversion: Conversion =
  387. { _ > sourceVar > filterInto(neededResult) }
  388. val dcontext = HashMap.empty ++ (for ((name, `neededResult`) <- bindingMap) yield { (name, bridge) })
  389. (sourceConversion, dcontext, id)
  390. }
  391. case neededResults => {
  392. /* More than one result is needed */
  393. /* Note: This can only occur in a strict pattern.
  394. * Thus, the source conversion for a non-strict pattern is always the identity function. */
  395. val sourceConversion: Conversion =
  396. { _ > sourceVar > filterInto(makeLet(neededResults)) }
  397. var dcontext: Map[String, Argument] = HashMap.empty
  398. var targetConversion = id
  399. for ((r, i) <- neededResults.zipWithIndex) {
  400. val y = new BoundVar()
  401. for ((name, `r`) <- bindingMap) {
  402. dcontext = dcontext + { (name, y) }
  403. }
  404. targetConversion = targetConversion compose { makeNth(bridge, i) > y > _ }
  405. }
  406. (sourceConversion, dcontext, targetConversion)
  407. }
  408. }
  409. }
  410. }