Commit 559c72dc authored by Kunshan Wang's avatar Kunshan Wang

Tested parser.

parent 3323a4b7
......@@ -2,8 +2,9 @@ package uvm
import uvm.types._
import uvm.ssavariables._
import scala.collection.mutable.HashMap
class Bundle {
abstract class Bundle {
/*
* There is a hierarchy of namespaces. A subnode is a subset of the parent.
*
......@@ -35,7 +36,30 @@ class Bundle {
val globalCellNs = globalVarNs.makeSubSpace[GlobalCell]()
val funcNs = globalVarNs.makeSubSpace[Function]()
val expFuncNs = globalVarNs.makeSubSpace[ExposedFunc]()
}
/**
* This kind of bundle is generated when parsing a .UIR file.
* <p>
* In this kind of bundle, a Function does not have a FuncVer as its version.
* The funcNs only contains new functions declared in this bundle, not existing
* functions declared previously. When this bundle is merged with the global bundle,
* both funcNs and funcVerNs are simply merged, and new FuncVer objects become the
* newest version of the Function, whether the Function is newly declared or not.
*/
class TrantientBundle extends Bundle {
/**
* All functions (declared here or previously) that are defined in this bundle.
* <p>
* Mainly for debugging purpose.
*/
//val defFuncNs = new SimpleNamespace[Function]
}
/**
* This kind of bundle holds the global state. Functions and versions are fully merged.
*/
class GlobalBundle extends Bundle {
private def simpleMerge[T <: Identified](oldNs: Namespace[T], newNs: Namespace[T]) {
for (cand <- newNs.all) {
try {
......@@ -49,7 +73,13 @@ class Bundle {
}
}
def merge(newBundle: Bundle) {
private def redefineFunctions(newNs: Namespace[FuncVer]) {
for (fv <- newNs.all) {
fv.func.versions = fv :: fv.func.versions
}
}
def merge(newBundle: TrantientBundle) {
// Only merge leaves
simpleMerge(typeNs, newBundle.typeNs)
simpleMerge(funcSigNs, newBundle.funcSigNs)
......@@ -58,5 +88,8 @@ class Bundle {
simpleMerge(globalCellNs, newBundle.globalCellNs)
simpleMerge(funcNs, newBundle.funcNs)
simpleMerge(expFuncNs, newBundle.expFuncNs)
redefineFunctions(newBundle.funcVerNs)
}
}
}
\ No newline at end of file
......@@ -18,12 +18,12 @@ class UIRTextReader(val idFactory: IDFactory) {
import UIRTextReader._
import uvm.ir.textinput.Later.Laterable
def read(ir: String, globalBundle: Bundle): Bundle = {
def read(ir: String, globalBundle: GlobalBundle): TrantientBundle = {
val input = new ANTLRInputStream(ir)
read(ir, input, globalBundle)
}
def read(ir: java.io.Reader, globalBundle: Bundle): Bundle = {
def read(ir: java.io.Reader, globalBundle: GlobalBundle): TrantientBundle = {
val sb = new StringBuilder()
val cb = new Array[Char](4096)
......@@ -57,7 +57,7 @@ class UIRTextReader(val idFactory: IDFactory) {
def getMessages(): String = buf.mkString("\n")
}
def read(source: String, ais: ANTLRInputStream, globalBundle: Bundle): Bundle = {
def read(source: String, ais: ANTLRInputStream, globalBundle: GlobalBundle): TrantientBundle = {
val ea = new AccumulativeAntlrErrorListener(source)
val lexer = new UIRLexer(ais)
......@@ -144,8 +144,8 @@ class UIRTextReader(val idFactory: IDFactory) {
case e: Exception => throw new TextIRParsingException(inCtx(ctx, s), e)
}
def read(ir: IrContext, globalBundle: Bundle): Bundle = {
val bundle = new Bundle()
def read(ir: IrContext, globalBundle: GlobalBundle): TrantientBundle = {
val bundle = new TrantientBundle()
// Resolve global entities. (If any resXxxx is not present, that's because it is simply not currently used)
......@@ -364,6 +364,7 @@ class UIRTextReader(val idFactory: IDFactory) {
}
case fdef: FuncDefContext => {
val func = findOldFunc(fdef.nam).getOrElse(declFunc(fdef.nam, fdef.funcSig))
//bundle.defFuncNs.add(func)
funcDefs += ((func, fdef))
}
case edef: FuncExpDefContext => {
......@@ -385,7 +386,7 @@ class UIRTextReader(val idFactory: IDFactory) {
addFuncVer(ver)
ver.func = func
func.versions = ver :: func.versions
//func.versions = ver :: func.versions // Don't override here. Let the MicroVM redefine functions.
def globalizeBB(name: String): String = globalize(name, verName)
......
......@@ -153,7 +153,6 @@ case class KillOld() extends CurStackAction
abstract class NewStackAction
case class PassValue(var argTy: Type, var arg: SSAVariable) extends NewStackAction
case class PassVoid() extends NewStackAction
case class ThrowExc(var exc: SSAVariable) extends NewStackAction
/**
......
......@@ -717,6 +717,6 @@ class TextIRWriterTest extends FlatSpec with Matchers {
println(ir)
val muBundle = new UIRTextReader(new IDFactory).read(ir, new uvm.Bundle())
val muBundle = new UIRTextReader(new IDFactory).read(ir, new uvm.GlobalBundle())
}
}
\ No newline at end of file
......@@ -3,25 +3,25 @@ package uvm.ir.textinput
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import uvm.Bundle
import uvm.GlobalBundle
import uvm.TrantientBundle
class NicerErrorMessage extends FlatSpec with Matchers
with TestingBundlesValidators {
def parseFile(fileName: String, globalBundle: Bundle, fac: Option[IDFactory] = None): Bundle = {
def parseFile(fileName: String, globalBundle: GlobalBundle, fac: Option[IDFactory] = None): TrantientBundle = {
val idf = fac.getOrElse(new IDFactory())
val r = new UIRTextReader(idf)
val ir = r.read(new java.io.FileReader(fileName), globalBundle)
ir
}
val EMPTY_BUNDLE = new Bundle()
behavior of "UIRTextReader"
it should "give nice error messages" in {
try {
val b = parseFile("tests/uvm-parsing-test/bundle-with-error.uir", EMPTY_BUNDLE)
val gb = new GlobalBundle()
val b = parseFile("tests/uvm-parsing-test/bundle-with-error.uir", gb)
} catch {
case e: TextIRParsingException => // expected
e.printStackTrace()
......
......@@ -3,48 +3,54 @@ package uvm.ir.textinput
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import uvm.Bundle
import uvm.GlobalBundle
import uvm.TrantientBundle
class UIRTextReaderSpec extends FlatSpec with Matchers
with TestingBundlesValidators {
class UIRTextReaderSpec extends FlatSpec with Matchers
with TestingBundlesValidators {
def parseFile(fileName: String, globalBundle: Bundle, fac: Option[IDFactory] = None): Bundle = {
def parseFile(fileName: String, globalBundle: GlobalBundle, fac: Option[IDFactory] = None): TrantientBundle = {
val idf = fac.getOrElse(new IDFactory())
val r = new UIRTextReader(idf)
val ir = r.read(new java.io.FileReader(fileName), globalBundle)
ir
}
val EMPTY_BUNDLE = new Bundle()
behavior of "UIRTextReader"
def parseFresh(fileName: String): GlobalBundle = {
val gb = new GlobalBundle()
val tb = parseFile(fileName, gb)
gb.merge(tb)
gb
}
it should "read simple type definitions" in {
val b = parseFile("tests/uvm-parsing-test/types.uir", EMPTY_BUNDLE)
val b = parseFresh("tests/uvm-parsing-test/types.uir")
validateTypes(b)
}
it should "read simple constant definitions" in {
val b = parseFile("tests/uvm-parsing-test/constants.uir", EMPTY_BUNDLE)
val b = parseFresh("tests/uvm-parsing-test/constants.uir")
validateConstants(b)
}
it should "read simple function definitions" in {
val b = parseFile("tests/uvm-parsing-test/functions.uir", EMPTY_BUNDLE)
val b = parseFresh("tests/uvm-parsing-test/functions.uir")
validateFunctions(b)
}
it should "read simple instruction definitions" in {
val b = parseFile("tests/uvm-parsing-test/instructions.uir", EMPTY_BUNDLE)
val b = parseFresh("tests/uvm-parsing-test/instructions.uir")
validateInstructions(b)
}
/*
it should "handle loading of multiple bundles" in {
val idf = new IDFactory()
val gb = parseFile("tests/uvm-parsing-test/redef-base.uir", EMPTY_BUNDLE, Some(idf))
val b = parseFile("tests/uvm-parsing-test/redef-overlay.uir", gb, Some(idf))
validateRedef(gb, b)
gb.merge(b)
validateRedefAfterMerge(gb, b)
val gb = new GlobalBundle()
val b1 = parseFile("tests/uvm-parsing-test/redef-base.uir", gb, Some(idf))
gb.merge(b1)
val b2 = parseFile("tests/uvm-parsing-test/redef-overlay.uir", gb, Some(idf))
validateRedef(gb, b1, b2)
gb.merge(b2)
validateRedefAfterMerge(gb, b2)
}
*/
}
\ No newline at end of file
This diff is collapsed.
......@@ -3,9 +3,9 @@
.funcsig @IntReturner = @i64 ()
.funcdef @meaning_of_life VERSION @meaning_of_life_v1 <@IntReturner> () {
%entry:
%ret = RET <@i64> @I64_42
.funcdef @meaning_of_life VERSION %v1 <@IntReturner> {
%entry():
%ret = RET @I64_42
}
.funcdecl @foxsay <@IntReturner>
......
.const @I64_99 <@i64> = 99
.const @I64_43 <@i64> = 43
.funcdef @foxsay VERSION @foxsay_v1 <@IntReturner> () {
%entry:
%ret = RET <@i64> @I64_99
.funcdef @foxsay VERSION %v1 <@IntReturner> {
%entry():
%ret = RET @I64_99
}
.funcdef @meaning_of_life VERSION @meaning_of_life_v2 <@IntReturner> () {
%entry:
%ret = RET <@i64> @I64_43
.funcdef @meaning_of_life VERSION %v2 <@IntReturner> {
%entry():
%ret = RET @I64_43
}
.expose @meaning_external2 = @meaning_of_life #DEFAULT @I64_43
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