Skip to content

Instantly share code, notes, and snippets.

@rightfold
Created October 10, 2014 19:15
Show Gist options
  • Save rightfold/73f5057ec6c0ff5ca107 to your computer and use it in GitHub Desktop.
Save rightfold/73f5057ec6c0ff5ca107 to your computer and use it in GitHub Desktop.
package org.rightfold.styx.compiler.semantic
import org.rightfold.styx.compiler.Diagnostic
import org.rightfold.styx.compiler.parse
class Analyzer(emitDiagnostic: Diagnostic => Unit) {
case object AnalysisFailed extends Exception
sealed abstract class Symbol {
def isUnsafe: Boolean
}
case class Context(parent: Option[Context], symbols: Map[String, Symbol], unsafe: Boolean) {
def addSymbol(name: String, symbol: Symbol) = {
if (symbols contains name) {
emitDiagnostic(Diagnostic(Diagnostic.Error, s"attempt to redefine symbol `$name`"))
// TODO: Emit info diagnostic containing position of original symbol
throw AnalysisFailed
}
copy(symbols = symbols + (name -> symbol))
}
def findSymbol(name: String): Option[Symbol] = {
val result = symbols.get(name) orElse (parent flatMap (_ findSymbol name))
if (!unsafe && result.nonEmpty && result.get.isUnsafe) {
emitDiagnostic(Diagnostic(Diagnostic.Error, s"attempt to use unsafe symbol `$name` in a safe context"))
throw AnalysisFailed
}
result
}
def mustFindSymbol(name: String): Symbol = findSymbol(name) match {
case Some(symbol) => symbol
case None =>
emitDiagnostic(Diagnostic(Diagnostic.Error, s"attempt to use undefined symbol `$name`"))
throw AnalysisFailed
}
def makeSafe = copy(unsafe = false)
def makeUnsafe = copy(unsafe = true)
}
def analyzeExpression(context: Context)(expression: parse.Expression): Expression = (expression match {
case parse.UnitExpression => UnitExpression
case parse.IntExpression(value) => IntExpression(value)
case parse.SafeExpression(body) => analyzeExpression(context.makeSafe)(body)
case parse.UnsafeExpression(body) => analyzeExpression(context.makeUnsafe)(body)
}) ensuring (_.`type`.kind == *)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment