From 959f4d9a05aec569cfb5cc759476a39995aed4a5 Mon Sep 17 00:00:00 2001 From: tmoux Date: Wed, 15 Jul 2020 11:50:08 -0500 Subject: [PATCH] fixing stuff --- selfhost/binding.wyv | 47 +++++++++--------- selfhost/failtests/badsubtype.wyv | 15 ++++++ selfhost/failtests/badsubtype2.wyv | 19 ++++++++ selfhost/main.wyv | 36 +++++++------- selfhost/run.sh | 6 +-- selfhost/tests/cloneable.wyv | 26 ++++++++++ selfhost/tests/lambdaTest.wyv | 4 +- selfhost/tests/monoid.wyv | 5 +- selfhost/tests/typemember.wyv | 7 +-- selfhost/toBytecode.wyv | 2 +- selfhost/typecheck.wyv | 78 ++++++++++++++---------------- selfhost/types.wyv | 33 ++++--------- selfhost/typesUtil.wyv | 28 ++++++++--- selfhost/wyvernLexer.wyv | 10 ++-- 14 files changed, 190 insertions(+), 126 deletions(-) create mode 100644 selfhost/failtests/badsubtype.wyv create mode 100644 selfhost/failtests/badsubtype2.wyv create mode 100644 selfhost/tests/cloneable.wyv diff --git a/selfhost/binding.wyv b/selfhost/binding.wyv index c15e67126..839fab867 100644 --- a/selfhost/binding.wyv +++ b/selfhost/binding.wyv @@ -15,19 +15,12 @@ def rawToType(s:raw.Type, ctx:types.Context):types.Type if (b.str == "Unit") types.UnitType() else - val pred = ((d:DeclType) => - val z = match d: - tt:types.TypeType => - if (tt.name.name == b.str) { option.Some[types.TypeType](tt) } else { option.None[types.TypeType]() } - default => option.None[types.TypeType]() - z - ) + val pred = typesUtil.findTypePredicateFromStr(b.str) val L = typesUtil.findInDeclList[types.TypeType](ctx.bindings, pred).name types.NominalType(L) path:raw.Path => val p = bindExpr(path.p,ctx) - val t = types.Binding(path.t,ctx.counter) //maybe should just be a String? - types.PathType(p,t) + types.PathType(p,path.t) val refines = s.refines.map[types.DeclType](e => bindDeclTypes(e,ctx)) types.Type(base,refines) @@ -39,12 +32,12 @@ def bindDeclTypes(e:raw.Exp, context:types.Context):DeclType = match e: val b = types.Binding(d.name, context.counter) var newCtx:types.Context = context - def mapParams(args:List[raw.Arg]):List[types.Arg] = match args: + def mapParams(args:List[raw.Arg]):List[types.ValType] = match args: c:llist.Cons => - val arg = types.Arg(types.Binding(c.value.arg,newCtx.counter),rawToType(c.value.argTyp,newCtx)) - newCtx = newCtx.extend(types.ValType(arg.arg,arg.argTyp)) - llist.Cons[types.Arg](arg,mapParams(c.next)) - n:llist.Nil => llist.Nil[types.Arg]() + val arg = types.ValType(types.Binding(c.value.arg,newCtx.counter),rawToType(c.value.argTyp,newCtx)) + newCtx = newCtx.extend(arg) + llist.Cons[types.ValType](arg,mapParams(c.next)) + n:llist.Nil => llist.Nil[types.ValType]() val arglist = mapParams(d.args) types.DefType(b, arglist, rawToType(d.retTyp,newCtx)) @@ -74,7 +67,17 @@ def makeSeq(e:raw.Exp):raw.Seq = match e: //ensures that the whole expression is default => raw.Seq(llist.Singleton[raw.Exp](e)) def bind(e:raw.Exp, parse: String -> raw.Exp):types.Statement - bindStatement(makeSeq(e), types.emptyContext(parse)) + bindTopLevel(e, types.emptyContext(parse)) + +def bindTopLevel(e:raw.Exp, context:types.Context):types.Statement + //add Unit type decl + val nameb = types.Binding("Unit",context.counter) + val zb = types.Binding("z",context.counter) + val unitTypeDecl = types.TypeDecl(nameb,zb,llist.Nil[DeclType]()) + val unitDeclType = types.TypeType(nameb,zb,llist.Nil[DeclType]()) + + val program = bindStatement(makeSeq(e),context.extend(unitDeclType)) + types.DeclStatement(unitTypeDecl,program) def bindStatement(e:raw.Seq, context:types.Context):types.Statement = match e.exps: c:llist.Cons => match c.next: @@ -114,12 +117,12 @@ def bindDecl(e:raw.Exp, context:types.Context):types.Decl = match e: val b = types.Binding(d.name, context.counter) var newCtx:types.Context = context - def mapParams(args:List[raw.Arg]):List[types.Arg] = match args: + def mapParams(args:List[raw.Arg]):List[types.ValType] = match args: c:llist.Cons => - val arg = types.Arg(types.Binding(c.value.arg,newCtx.counter),rawToType(c.value.argTyp,newCtx)) - newCtx = newCtx.extend(types.ValType(arg.arg,arg.argTyp)) - llist.Cons[types.Arg](arg,mapParams(c.next)) - n:llist.Nil => llist.Nil[types.Arg]() + val arg = types.ValType(types.Binding(c.value.arg,newCtx.counter),rawToType(c.value.argTyp,newCtx)) + newCtx = newCtx.extend(arg) + llist.Cons[types.ValType](arg,mapParams(c.next)) + n:llist.Nil => llist.Nil[types.ValType]() val arglist = mapParams(d.args) val methodDecl = types.DefType(b, arglist, rawToType(d.retTyp,newCtx)) @@ -185,8 +188,8 @@ def bindExpr(e:raw.Exp, context:types.Context):types.Exp = match e: val expType = typecheck.typecheckExpr(boundExp, newCtx.bindings) val applyb = types.Binding("apply", context.counter) - val decl = types.DefType(applyb, llist.Singleton[types.Arg](types.Arg(argb,argDecl.typ)), expType) - val defDeclaration:types.Decl = types.Def(applyb, llist.Singleton[types.Arg](types.Arg(argb,argDecl.typ)), expType, types.ExprStatement(boundExp)) + val decl = types.DefType(applyb, llist.Singleton[types.ValType](types.ValType(argb,argDecl.typ)), expType) + val defDeclaration:types.Decl = types.Def(applyb, llist.Singleton[types.ValType](types.ValType(argb,argDecl.typ)), expType, types.ExprStatement(boundExp)) val thisb = types.Binding("_this", context.counter) val thisType = types.makeRefines(llist.Singleton[DeclType](decl)) diff --git a/selfhost/failtests/badsubtype.wyv b/selfhost/failtests/badsubtype.wyv new file mode 100644 index 000000000..59b21d7ff --- /dev/null +++ b/selfhost/failtests/badsubtype.wyv @@ -0,0 +1,15 @@ +type Int:z: + def +(i:Int):Int + def -(i:Int):Int + +type A:z: + type T >= Int + val a:z.T + +type B:z: + type T <= Int + val a:z.T + +subtype B extends A + +0 diff --git a/selfhost/failtests/badsubtype2.wyv b/selfhost/failtests/badsubtype2.wyv new file mode 100644 index 000000000..1626bcccb --- /dev/null +++ b/selfhost/failtests/badsubtype2.wyv @@ -0,0 +1,19 @@ +type Int:z: + def +(i:Int):Int + def -(i:Int):Int + +type A:z: + type T >= Int + val a:z.T + +type B:z: + type T <= Int + val a:z.T + +type C:z: + val a:Int + +subtype Unit {val a:Int} extends C +subtype Unit {val a:Int} extends A + +0 diff --git a/selfhost/main.wyv b/selfhost/main.wyv index 542b23d51..7a4d1f18c 100644 --- a/selfhost/main.wyv +++ b/selfhost/main.wyv @@ -63,23 +63,24 @@ def parse(s:String):raw.Exp stdout.print("Binding...\n") val boundExp:types.Statement = binding.bind(parser.results.get(0), s => parse(s)) -//val boundExp : exception.Answer[types.Statement,exception.Exception] = exception.try[types.Statement](() => binding.bind(parser.results.get(0), s => parse(s))) -//match boundExp: -// s1: exception.Success => -// stdout.print("binding success\n") -// val tc:exception.Answer[types.Type,exception.Exception] = exception.try[types.Type](() => typecheck.typecheck(s1.value)) -// match tc: -// s1: exception.Success => -// stdout.print("type: " + typesUtil.typeToString(s1.value) + "\n") -// f1: exception.Failure => -// match f1.exception: -// exn: error.ErrorReportingException => stdout.print(error.asString(exn)+"\n") -// default => stdout.print("unexpected exception thrown\n") -// f1: exception.Failure => -// match f1.exception: -// exn: error.ErrorReportingException => stdout.print(error.asString(exn)+"\n") -// default => stdout.print("unexpected exception thrown\n") - +val boundExp : exception.Answer[types.Statement,exception.Exception] = exception.try[types.Statement](() => binding.bind(parser.results.get(0), s => parse(s))) +match boundExp: + s1: exception.Success => + stdout.print("binding success\n") + val tc:exception.Answer[types.Type,exception.Exception] = exception.try[types.Type](() => typecheck.typecheck(s1.value)) + match tc: + s1: exception.Success => + stdout.print("type: " + typesUtil.typeToString(s1.value) + "\n") + f1: exception.Failure => + match f1.exception: + exn: error.ErrorReportingException => stdout.print(error.asString(exn)+"\n") + default => stdout.print("unexpected exception thrown\n") + f1: exception.Failure => + match f1.exception: + exn: error.ErrorReportingException => stdout.print(error.asString(exn)+"\n") + default => stdout.print("unexpected exception thrown\n") + +/* val tc = typecheck.typecheck(boundExp) stdout.print("type: " + typesUtil.typeToString(tc) + "\n") @@ -93,3 +94,4 @@ stdout.print(outputFileName) stdout.print("...\n") toBytecode.writeExpToFile(ooExp, outputFileName) +*/ diff --git a/selfhost/run.sh b/selfhost/run.sh index 01ef69248..656b3286a 100755 --- a/selfhost/run.sh +++ b/selfhost/run.sh @@ -7,6 +7,6 @@ wyby main.wyv node ../backend/boot.js main.wyb > main.js node main.js $1 -echo FINISHED PRODUCING WYB FILE FOR $1 NOW RUNNING IT -node ../backend/boot.js `echo $1 | sed 's/\.wyv/\.wyb/'` > `echo $1 | sed 's/\.wyv/\.js/'` -node `echo $1 | sed 's/\.wyv/\.js/'` +#echo FINISHED PRODUCING WYB FILE FOR $1 NOW RUNNING IT +#node ../backend/boot.js `echo $1 | sed 's/\.wyv/\.wyb/'` > `echo $1 | sed 's/\.wyv/\.js/'` +#node `echo $1 | sed 's/\.wyv/\.js/'` diff --git a/selfhost/tests/cloneable.wyv b/selfhost/tests/cloneable.wyv new file mode 100644 index 000000000..b28a3a8ca --- /dev/null +++ b/selfhost/tests/cloneable.wyv @@ -0,0 +1,26 @@ +type Int:z: + def +(i:Int):Int + def -(i:Int):Int + +type Cloneable:z: + type T <= Unit + def clone(u:Unit):z.T + +type String:z: + type T <= String + def clone(u:Unit):z.T +subtype String extends Cloneable + +type A:z: + def makeClone(arg:Cloneable):arg.T +val a = new this:A: + def makeClone(arg:Cloneable):arg.T: + arg.clone(()) + +val s = new this:String: + type T <= String + def clone(u:Unit):this.T: + a.makeClone(this) + + +a.makeClone(s) diff --git a/selfhost/tests/lambdaTest.wyv b/selfhost/tests/lambdaTest.wyv index 4fc9ec6c7..def17f2f3 100644 --- a/selfhost/tests/lambdaTest.wyv +++ b/selfhost/tests/lambdaTest.wyv @@ -1,7 +1,7 @@ -type Int: +type Int:z: def +(i:Int):Int def -(i:Int):Int val succ = x:Int => x + 1 val fst = x:Int => y:Int => x -fst 7 +fst diff --git a/selfhost/tests/monoid.wyv b/selfhost/tests/monoid.wyv index a464b5bdd..aa4c78b23 100644 --- a/selfhost/tests/monoid.wyv +++ b/selfhost/tests/monoid.wyv @@ -10,6 +10,7 @@ type Monoid:z: type T <= Unit val id:z.T def op(a:z.T, b:z.T):z.T +subtype Monoid extends Semi val sum = new this:Monoid {type T = Int}: type T = Int @@ -18,10 +19,10 @@ val sum = new this:Monoid {type T = Int}: a + b type Util:z: - def apply3(s:Monoid, a:s.T, b:s.T, c:s.T):s.T + def apply3(s:Semi, a:s.T, b:s.T, c:s.T):s.T val util = new this:Util: - def apply3(s:Monoid, a:s.T, b:s.T, c:s.T):s.T: + def apply3(s:Semi, a:s.T, b:s.T, c:s.T):s.T: s.op(a,s.op(b,c)) val ans = util.apply3(sum,1,2,3) diff --git a/selfhost/tests/typemember.wyv b/selfhost/tests/typemember.wyv index 66e592dee..26455873e 100644 --- a/selfhost/tests/typemember.wyv +++ b/selfhost/tests/typemember.wyv @@ -4,19 +4,20 @@ type Int:z: type Equatable:z: type T <= Unit - def equals(x:z.T):Int + def equals(x:z.T):z.T type Fruit:z: type T <= Unit type S <= Unit val item:z.T - def equals(x:z.T):Int + def equals(x:z.T):z.T +subtype Fruit extends Equatable val f1 = new this:Fruit {type T = Int}: type T = Int type S <= Unit val item:this.T = 3 - def equals(x:this.T):Int: + def equals(x:this.T):this.T: this.item + x f1.equals(3) diff --git a/selfhost/toBytecode.wyv b/selfhost/toBytecode.wyv index ae93e8e3f..9de0e20e3 100644 --- a/selfhost/toBytecode.wyv +++ b/selfhost/toBytecode.wyv @@ -21,7 +21,7 @@ def toBytecodeStmt(e:types.Statement):List[b.SeqStmt] = match e: def toBytecodeDecl(e:types.Decl):b.Decl = match e: v:types.Val => b.ValDecl(v.binding.name, toBytecodeExpr(v.exp)) - d:types.Def => b.MethodDecl(d.binding.name, d.args.map[String](e => e.arg.name), b.SeqExpr(toBytecodeStmt(d.body))) + d:types.Def => b.MethodDecl(d.binding.name, d.args.map[String](e => e.name.name), b.SeqExpr(toBytecodeStmt(d.body))) t:types.TypeDecl => b.ValDecl("_", toBytecodeExpr(types.UnitVal())) s:types.SubtypeDecl => b.ValDecl("_", toBytecodeExpr(types.UnitVal())) m:types.TypeEq => b.ValDecl("_", toBytecodeExpr(types.UnitVal())) diff --git a/selfhost/typecheck.wyv b/selfhost/typecheck.wyv index 912f14551..f3420bf21 100644 --- a/selfhost/typecheck.wyv +++ b/selfhost/typecheck.wyv @@ -39,10 +39,10 @@ def typecheckDecl(e:types.Decl, gamma:List[DeclType]):DeclType = match e: val typ = typecheckExpr(v.exp, gamma) types.ValType(v.binding, typ) t:types.TypeDecl => + //TODO: check WF here types.TypeType(t.name, t.z, t.typ) d:types.Def => - val argdecls:List[DeclType] = d.args.map[ValType]((a:types.Arg) => types.ValType(a.arg,a.argTyp)) - val ngamma = argdecls.append(gamma) + val ngamma = d.args.map[DeclType](e=>e).append(gamma) val testType = typecheckStmt(d.body, ngamma) if (isSubtype(testType, d.retTyp, ngamma)) types.DefType(d.binding, d.args, d.retTyp) @@ -75,9 +75,9 @@ def typecheckExpr(e:types.Exp, gamma:List[DeclType]):Type = match e: val pred = ((b:DeclType) => val z = match b: da:DefType => - val argBindings = da.args.map[Binding](a => a.arg) + val argBindings = da.args.map[Binding](a => a.name) - val argsSub = da.args.map[ValType](e => types.ValType(e.arg,types.substituteType(e.argTyp,c.receiver,unfold.z))) + val argsSub = da.args.map[ValType](e => types.ValType(e.name,types.substituteType(e.typ,c.receiver,unfold.z))) val argsSub2 = argsSub.map[ValType](e => types.ValType(e.name,typesUtil.doListOfSubstitutions(e.typ,c.args,argBindings))) val defargs = argsSub2.map[Type](e => e.typ) @@ -92,7 +92,7 @@ def typecheckExpr(e:types.Exp, gamma:List[DeclType]):Type = match e: val func = typesUtil.findInDeclList[DefType](unfold.decls, pred) //Do substitutions to get the correct return type val retTyp = types.substituteType(func.retTyp, c.receiver, unfold.z) - val argBindings = func.args.map[Binding](a => a.arg) + val argBindings = func.args.map[Binding](a => a.name) typesUtil.doListOfSubstitutions(retTyp,c.args,argBindings) f:types.Field => //T-Field @@ -146,26 +146,18 @@ def typecheckExpr(e:types.Exp, gamma:List[DeclType]):Type = match e: ///////////////////////////////// //UNFOLD type Unfold - val z:Option[Binding] + val z:Binding val decls:List[DeclType] -def Unfold(z:Option[Binding], decls:List[DeclType]):Unfold = new +def Unfold(z:Binding, decls:List[DeclType]):Unfold = new val z = z val decls = decls -def findTypePredicate(bind:Binding):DeclType->Option[TypeType] - val pred = ((b:DeclType) => - val z = match b: - t:TypeType => if (types.equalBinding(bind, t.name)) { option.Some[TypeType](t) } else { option.None[TypeType]() } - default => option.None[TypeType]() - z - ) - pred def fetchDeclFromList(path:PathType, ls:List[DeclType]):DeclType val pred = ((d:DeclType) => val z = match d: - t:TypeType => path.t.name == t.name.name - m:MemberType => path.t.name == m.name.name //compare just names instead of bindings? I think its ok since just searching in an unfld list like for field names + t:TypeType => path.t == t.name.name + m:MemberType => path.t == m.name.name default => false z ) @@ -176,11 +168,14 @@ def fetchDeclFromList(path:PathType, ls:List[DeclType]):DeclType def unfoldType(x:Type, gamma:List[DeclType]):Unfold val b = match x.base: - u:UnitType => Unfold(option.None[Binding](),llist.Nil[DeclType]()) + u:UnitType => + val pred = typesUtil.findTypePredicateFromStr("Unit") + val tt = typesUtil.findInDeclList[TypeType](gamma, pred) + Unfold(tt.z,llist.Nil[DeclType]()) x:NominalType => - val pred = findTypePredicate(x.L) + val pred = typesUtil.findTypePredicate(x.L) val tt = typesUtil.findInDeclList[TypeType](gamma, pred) - Unfold(option.Some[Binding](tt.z),tt.unfld) + Unfold(tt.z,tt.unfld) path:PathType => val tau = typecheckExpr(path.p,gamma) val pUnfold = unfoldType(tau,gamma) @@ -188,9 +183,12 @@ def unfoldType(x:Type, gamma:List[DeclType]):Unfold match d: t:TypeType => val subUnfold = t.unfld.map[DeclType](e => types.substituteDeclType(e,path.p,pUnfold.z)) - Unfold(option.Some[Binding](t.z),subUnfold) + Unfold(t.z,subUnfold) m:MemberType => match m.bound: - g:types.GEQ => Unfold(option.None[Binding](),llist.Nil[DeclType]()) + g:types.GEQ => + val pred = typesUtil.findTypePredicateFromStr("Unit") + val tt = typesUtil.findInDeclList[TypeType](gamma, pred) + Unfold(tt.z,llist.Nil[DeclType]()) default => unfoldType(types.substituteType(m.typ,path.p,pUnfold.z),gamma) default => error.report("should never happend",error.unknownLocation) Unfold(b.z,x.refines.append(b.decls)) @@ -228,10 +226,10 @@ def equalDeclType(a:DeclType, b:DeclType, gamma:List[DeclType]):Boolean = match default => false d:DefType => match b: u:DefType => - val dargs = d.args.map[Type](e => e.argTyp) - val uargs = u.args.map[Type](e => e.argTyp) - val ngamma = d.args.map[DeclType](e => types.ValType(e.arg,e.argTyp)).append(gamma) - val nngamma = u.args.map[DeclType](e => types.ValType(e.arg,e.argTyp)).append(ngamma) + val dargs = d.args.map[Type](e => e.typ) + val uargs = u.args.map[Type](e => e.typ) + val ngamma = d.args.map[DeclType](e=>e).append(gamma) + val nngamma = u.args.map[DeclType](e=>e).append(ngamma) val pred = x:Type => y:Type => equalType(x,y,nngamma) d.name.name == u.name.name && checkArgList(dargs,uargs,pred) && equalType(d.retTyp,u.retTyp,nngamma) default => false @@ -255,7 +253,7 @@ def equalBaseType(a:BaseType, b:BaseType, gamma:List[DeclType]):Boolean = match v:PathType => val tauA = typecheckExpr(path.p,gamma) val tauB = typecheckExpr(v.p,gamma) - equalType(tauA,tauB,gamma) && path.t.name == v.t.name + equalType(tauA,tauB,gamma) && path.t == v.t default => false def equalType(t1:Type, t2:Type, gamma:List[DeclType]):Boolean @@ -274,10 +272,10 @@ def isSubtypeDecl(a:DeclType, b:DeclType, gamma:List[DeclType]):Boolean = match default => false d:DefType => match b: u:DefType => - val dargs = d.args.map[Type](e => e.argTyp) - val uargs = u.args.map[Type](e => e.argTyp) - val ngamma = d.args.map[DeclType](e => types.ValType(e.arg,e.argTyp)).append(gamma) - val nngamma = u.args.map[DeclType](e => types.ValType(e.arg,e.argTyp)).append(ngamma) + val dargs = d.args.map[Type](e => e.typ) + val uargs = u.args.map[Type](e => e.typ) + val ngamma = d.args.map[DeclType](e=>e).append(gamma) + val nngamma = u.args.map[DeclType](e=>e).append(ngamma) val pred = x:Type => y:Type => isSubtype(x,y,nngamma) d.name.name == u.name.name && checkArgList(uargs,dargs,pred) && isSubtype(d.retTyp,u.retTyp,nngamma) default => false @@ -372,16 +370,12 @@ def isSubtypeBase(t1:Type, t2:BaseType, gamma:List[DeclType]):Boolean def checkSubtypeWF(t1:Type, t2:Type, gamma:List[DeclType]):Boolean val ua = unfoldType(t1,gamma) val ub = unfoldType(t2,gamma) - var newgamma:List[DeclType] = llist.Cons[DeclType](types.SubtypeType(t1,t2),gamma) - match ua.z: - s:option.Some => - val vt = types.ValType(s.get(),t1) - newgamma = llist.Cons[DeclType](vt,newgamma) - match ub.z: - s:option.Some => - val vt = types.ValType(s.get(),t2) - newgamma = llist.Cons[DeclType](vt,newgamma) - //val ng:List[DeclType] = newgamma + val ngamma = llist.Cons[DeclType](types.SubtypeType(t1,t2),gamma) + val nngamma = llist.Cons[DeclType](types.ValType(ua.z,t1),ngamma) + //ADD ua.z to ctx, substitute ub.z for ua.z + val supertypeDecls = ub.decls.map[DeclType](d => types.substituteDeclType(d,types.Var(ua.z),ub.z)) //error.report("ngamma: \n" + typesUtil.combineWithNewlines(ng.map[String](e => typesUtil.declTypeToString(e))),error.unknownLocation) - isSubtypeDeclList(ua.decls,ub.decls,newgamma) + isSubtypeDeclList(ua.decls,supertypeDecls,nngamma) +def checkTypeDeclWF(d:DeclType,gamma:List[DeclType]):Boolean + true diff --git a/selfhost/types.wyv b/selfhost/types.wyv index b707af7cd..aea6313a2 100644 --- a/selfhost/types.wyv +++ b/selfhost/types.wyv @@ -47,21 +47,13 @@ def Context(bs:List[DeclType], c:Counter, p:String -> raw.Exp) : Context = new def emptyContext(p:String -> raw.Exp):Context = Context(llist.Nil[DeclType](), Counter(), p) -//TODO: ARG should really just be a valType to make things easier -type Arg - val arg:Binding - val argTyp:Type -def Arg(arg:Binding,argTyp:Type):Arg = new - val arg = arg - val argTyp = argTyp - datatype Statement DeclStatement(decl:Decl, stmt:Statement) ExprStatement(exp:Exp) datatype Decl Val(binding:Binding, typ:Type, exp:Exp) - Def(binding:Binding, args:List[Arg], retTyp:Type, body:Statement) + Def(binding:Binding, args:List[ValType], retTyp:Type, body:Statement) TypeDecl(name:Binding, z:Binding, typ:List[DeclType]) SubtypeDecl(subtype:Type, supertype:Type) TypeEq(name:Binding, typ:Type) @@ -78,7 +70,7 @@ datatype Exp datatype BaseType UnitType() NominalType(L:Binding) - PathType(p:Exp, t:Binding) + PathType(p:Exp, t:String) type Type val base:BaseType @@ -101,34 +93,29 @@ datatype Bound datatype DeclType ValType(name:Binding, typ:Type) TypeType(name:Binding, z:Binding, unfld:List[DeclType]) - DefType(name:Binding, args:List[Arg], retTyp:Type) + DefType(name:Binding, args:List[ValType], retTyp:Type) SubtypeType(subtype:Type, supertype:Type) MemberType(name:Binding, bound:Bound, typ:Type) val theUnit = Type(UnitType(),llist.Nil[DeclType]()) ////////////////////////////// -def substituteBaseType(beta:BaseType, newb:Exp, oldb:Option[Binding]):BaseType = match beta: +def substituteBaseType(beta:BaseType, newb:Exp, oldb:Binding):BaseType = match beta: p:PathType => PathType(substituteExp(p.p,newb,oldb),p.t) default => beta -def substituteType(tau:Type, newb:Exp, oldb:Option[Binding]):Type +def substituteType(tau:Type, newb:Exp, oldb:Binding):Type val subBase = substituteBaseType(tau.base,newb,oldb) val subRefines = tau.refines.map[DeclType](e => substituteDeclType(e,newb,oldb)) Type(subBase,subRefines) -def substituteDeclType(d:DeclType, newb:Exp, oldb:Option[Binding]):DeclType = match d: +def substituteDeclType(d:DeclType, newb:Exp, oldb:Binding):DeclType = match d: v:ValType => ValType(v.name,substituteType(v.typ,newb,oldb)) t:TypeType => TypeType(t.name,t.z,t.unfld.map[DeclType](e => substituteDeclType(e,newb,oldb))) - d:DefType => DefType(d.name,d.args.map[Arg](e=>Arg(e.arg,substituteType(e.argTyp,newb,oldb))),substituteType(d.retTyp,newb,oldb)) + d:DefType => DefType(d.name,d.args.map[ValType](e=>ValType(e.name,substituteType(e.typ,newb,oldb))),substituteType(d.retTyp,newb,oldb)) s:SubtypeType => SubtypeType(substituteType(s.subtype,newb,oldb),substituteType(s.supertype,newb,oldb)) m:MemberType => MemberType(m.name,m.bound,substituteType(m.typ,newb,oldb)) -def substituteExp(e:Exp, newb:Exp, oldb:Option[Binding]):Exp = match e: - v:Var => match oldb: - s:option.Some => if (equalBinding(v.binding,s.get())) { newb } else { v } - default => v - c:Call => Call(substituteExp(c.receiver,newb,oldb),c.name,c.args.map[Exp](e => substituteExp(e,newb,oldb))) +def substituteExp(e:Exp, newb:Exp, oldb:Binding):Exp = match e: + v:Var => if (equalBinding(v.binding, oldb)) { newb } else { v } f:Field => Field(substituteExp(f.receiver,newb,oldb),f.field) - n:New => error.report("TODO: substitute new",error.unknownLocation) //fix this--need to add substitute Decl and Statement, probably - i:Integer => i - u:UnitVal => u + default => error.report("Substitution into invalid path type",error.unknownLocation) diff --git a/selfhost/typesUtil.wyv b/selfhost/typesUtil.wyv index 19ffe5373..d6d3d0920 100644 --- a/selfhost/typesUtil.wyv +++ b/selfhost/typesUtil.wyv @@ -41,7 +41,7 @@ def zip[U,T](xs:List[U], ys:List[T]):List[Pair[U,T]] = match xs: def doListOfSubstitutions(ty:Type, exps:List[types.Exp], bindings:List[Binding]):Type val zipargs = zip[types.Exp,Binding](exps,bindings) - zipargs.foldRight[Type]((x:Pair[types.Exp,Binding],t:Type)=>types.substituteType(t,x.first,option.Some[Binding](x.second)),ty) + zipargs.foldRight[Type]((x:Pair[types.Exp,Binding],t:Type)=>types.substituteType(t,x.first,x.second),ty) def equalBound(a:types.Bound, b:types.Bound):Boolean = match a: x:types.LEQ => match b: @@ -57,6 +57,24 @@ def equalBound(a:types.Bound, b:types.Bound):Boolean = match a: def addRefines(t:Type, decls:List[DeclType]):Type types.Type(t.base,decls.append(t.refines)) +def findTypePredicate(bind:Binding):DeclType->Option[TypeType] + val pred = ((b:DeclType) => + val z = match b: + t:TypeType => if (types.equalBinding(bind, t.name)) { option.Some[TypeType](t) } else { option.None[TypeType]() } + default => option.None[TypeType]() + z + ) + pred + +def findTypePredicateFromStr(s:String):DeclType->Option[TypeType] + val pred = ((d:DeclType) => + val z = match d: + tt:types.TypeType => + if (tt.name.name == s) { option.Some[types.TypeType](tt) } else { option.None[types.TypeType]() } + default => option.None[types.TypeType]() + z + ) + pred ///////////////////////// def combineWithNewlines(ls:List[String]):String = match ls: c:llist.Cons => match c.next: @@ -76,7 +94,7 @@ def declTypeToString(d:DeclType):String = match d: val s = t.unfld.map[String](e => declTypeToString(e)) "type " + t.name.name + ":" + " {" + combineStringList(s) + "}" d:DefType => - val arglist = d.args.map[String](t => t.arg.name + ":" + typeToString(t.argTyp)) + val arglist = d.args.map[String](t => t.name.name + ":" + typeToString(t.typ)) "def " + d.name.name + "(" + combineStringList(arglist) + "):" + typeToString(d.retTyp) s:SubtypeType => "subtype " + typeToString(s.subtype) + " extends " + typeToString(s.supertype) m:MemberType => @@ -85,13 +103,12 @@ def declTypeToString(d:DeclType):String = match d: a:types.EQ => " = " a:types.GEQ => " >= " "type " + m.name.name + boundStr + typeToString(m.typ) - default => error.report("missed case",error.unknownLocation) def typeToString(t:Type):String val baseString = match t.base: u:UnitType => "Unit" n:NominalType => n.L.name - path:PathType => expToString(path.p) + "." + path.t.name + path:PathType => expToString(path.p) + "." + path.t val s = t.refines.map[String](e => declTypeToString(e)) val refinesString = combineStringList(s) baseString + " {" + refinesString + "}" @@ -102,7 +119,6 @@ def expToString(e:types.Exp):String = match e: val argList = c.args.map[String](e => expToString(e)) expToString(c.receiver) + "." + c.name + "(" + combineStringList(argList) + ")" f:types.Field => expToString(f.receiver) + "." + f.field - n:types.New => error.report("TODO: new bound exp to string",error.unknownLocation) + n:types.New => "new" i:types.Integer => i.str u:types.UnitVal => "()" - default => error.report("missed case",error.unknownLocation) diff --git a/selfhost/wyvernLexer.wyv b/selfhost/wyvernLexer.wyv index 03ea74457..385c5b5c0 100644 --- a/selfhost/wyvernLexer.wyv +++ b/selfhost/wyvernLexer.wyv @@ -220,7 +220,7 @@ def makeSecondLevelLexer():SecondLevelLexer = new (self) => def handleLine(pending_:List[Dyn], tokens:List[Token]):List[Dyn] //inLine = true var toks:List[Dyn] = tokens - printTokens(toks) + //printTokens(toks) var pending:List[Dyn] = pending_ // in reverse order def computeDedents(matchingType:String):Unit @@ -280,9 +280,9 @@ def makeSecondLevelLexer():SecondLevelLexer = new (self) => def lexLines(input:String):List[Dyn] val lineMatch = regexUtils.doMatch(input, "[^\\r\\n]*") if (lineMatch.found) - js.log("reading line \"" + lineMatch.matched + "\"") + //js.log("reading line \"" + lineMatch.matched + "\"") val firstTokens = self.lexLine(lineMatch.matched) - printTokens(firstTokens) + //printTokens(firstTokens) if (lineMatch.after == "") def getBlocks():List[Dyn] val topState = self.lexerState.nth(0).getOrElse(() => DontCare()) @@ -335,9 +335,9 @@ def initLexer(toks : List[Dyn]):lexing.Lexer //js.log("lexer returning " + token.value) c.value n:llist.Nil => js.getUndefined() - def save():Dyn = js.log("called save\n") + def save():Dyn = unit //js.log("called save\n") def reset(chunk:String, info:Dyn):Unit - js.log("called reset\n") + //js.log("called reset\n") val secondLevelLexer = makeSecondLevelLexer() tokens = secondLevelLexer.lexLines(chunk).filter((t:Dyn) => !js.equalsJS("WS", t."type")) //tokens.do((t:Dyn) => printToken(t))