diff options
Diffstat (limited to 'src/main/stanza/errors.stanza')
| -rw-r--r-- | src/main/stanza/errors.stanza | 227 |
1 files changed, 128 insertions, 99 deletions
diff --git a/src/main/stanza/errors.stanza b/src/main/stanza/errors.stanza index 63199b4b..3e388a42 100644 --- a/src/main/stanza/errors.stanza +++ b/src/main/stanza/errors.stanza @@ -138,76 +138,44 @@ defn contains?<?T> (c:?T,cs:Streamable<?T>) -> True|False : if x == c : myret(true) false -;defstruct Trie : -; char : Char -; children : HashTable<Char,Trie> -; -;defn char-hash (c:Char) -> Int : symbol-hash(to-symbol(c)) -;defn new-trie (c:Char) -> Trie : Trie(c,HashTable<Char,Trie>(char-hash)) -;defn tail (s:String) -> String : substring(s,1,length(s)) -; -;defn insert-top (trie:Trie,symbol:Symbol) -> True|False : true -; insert(trie,string-join([" " symbol])) -; -;defn insert (trie:Trie,string:String) -> True|False : -; if length(string) == 0 : char(trie) -; -; val child = get?(children(trie),string[0],false) -; if length(string) == 1 : -; match(child) : -; (c:Trie) : false -; (c:False) : -; children(trie)[string[0]] = new-trie(string[0]) -; true -; else : -; match(child) : -; (c:Trie) : insert(c,tail(string)) -; (c:False) : -; val t = new-trie(string[0]) -; insert(t,tail(string)) -; children(trie)[string[0]] = t -; -;defn has? (trie:Trie, string:String) -> True|False : -; if length(string) == 0 : true -; if length(string) >= 1 : -; if key?(children(trie),string[0]) : -; has?(tail(string), children(trie)[string[0]]) -; else : false -; -;defn any-prefixes? (trie:Trie,delim:String) -> String|False : -; if has?(trie,delim) : -; val c = get-children-after(trie:Trie,delim:String) -; if length(keys(c)) > 1 : -; -; -; if length(partial-delim) == 0 : to-string(char(trie)) -; if length(partial-delim) == 1 : -; if key?(children(trie),partial-delim[0]) : any-prefixes?(...WAS HERE -; if char(trie) == partial-delim[0] : -; if length(keys(children(trie))) >= 2 : to-string(char(trie)) -; else : false -; else : -; label<String|False> myret : -; for x in children(trie) do : -; match(any-prefixes?(value(x),full-delim,full-delim)) : -; (s:False) : false -; (s:String) : myret(string-join([char(trie) s])) -; false -; else : -; label<String|False> myret : -; for x in children(trie) do : -; if char(trie) == partial-delim[0] : -; match(any-prefixes?(value(x),tail(partial-delim),full-delim)) : -; (s:False) : false -; (s:String) : myret(string-join([char(trie) s])) -; match(any-prefixes?(value(x),partial-delim,full-delim)) : -; (s:False) : false -; (s:String) : myret(string-join([char(trie) s])) -; match(any-prefixes?(value(x),full-delim,full-delim)) : -; (s:False) : false -; (s:String) : myret(string-join([char(trie) s])) -; false - +;--------------- Prefix Checker -------------------- + +defstruct Trie : + children : HashTable<Symbol,Trie> + end? : True|False with: (setter => set-end) + +defmethod print (o:OutputStream,t:Trie) : + print-all(o,["[end?:" end?(t) ",children:" children(t) "]"]) + +defn split (s:Symbol) -> List<Symbol> : + map(to-symbol,split(to-string(s),'$')) + +defn contains? (t:Trie,s:Symbol) -> True|False : + key?(children(t),s) + +defn empty? (t:Trie) -> True|False : + length(children(t)) == 0 + +defn add (t:Trie,ls:List<Symbol>) -> True|False : + var t*:Trie = t + var saw-end? = false + for x in ls do : + if end?(t*) : saw-end? = true + if contains?(t*,x) : t* = children(t*)[x] + else : + val temp = Trie(HashTable<Symbol,Trie>(symbol-hash),false) + children(t*)[x] = temp + t* = temp + set-end(t*,true) + saw-end? or not empty?(t*) + +defn contains? (t:Trie,ls:List<Symbol>) -> True|False : + var t*:Trie = t + label<True|False> myret : + for x in ls do : + if contains?(t*,x) : t* = children(t*)[x] + else : myret(false) + myret(end?(t*)) ;--------------- Check High Form Pass ------------------- public defn check-high-form (c:Circuit) -> Circuit : @@ -236,7 +204,7 @@ public defn check-high-form (c:Circuit) -> Circuit : NEQUAL-OP : correct-num(2,0) EQUIV-OP : correct-num(2,0) NEQUIV-OP : correct-num(2,0) - MUX-OP : correct-num(3,0) + ;MUX-OP : correct-num(3,0) PAD-OP : correct-num(1,1) AS-UINT-OP : correct-num(1,0) AS-SINT-OP : correct-num(1,0) @@ -290,10 +258,11 @@ public defn check-high-form (c:Circuit) -> Circuit : defn check-high-form-m (m:Module) -> Module : val names = HashTable<Symbol,True>(symbol-hash) val mnames = HashTable<Symbol,True>(symbol-hash) + val tries = Trie(HashTable<Symbol,Trie>(symbol-hash),false) defn check-high-form-e (e:Expression) -> Expression : defn valid-subexp (e:Expression) -> Expression : match(e) : - (e:Ref|SubField|SubIndex|SubAccess) : false + (e:Ref|SubField|SubIndex|SubAccess|Mux|ValidIf) : false (e) : add(errors,InvalidAccess()) e match(map(check-high-form-e,e)) : @@ -301,6 +270,7 @@ public defn check-high-form (c:Circuit) -> Circuit : if not key?(names,name(e)) : add(errors,UndeclaredReference(name(e))) (e:DoPrim) : check-high-form-primop(e) + (e:Mux|ValidIf) : e (e:UIntValue) : false (e:SubAccess) : valid-subexp(exp(e)) @@ -313,7 +283,9 @@ public defn check-high-form (c:Circuit) -> Circuit : defn check-name (name:Symbol) -> Symbol : if key?(names,name) : add(errors,NotUnique(name)) else : names[name] = true - name + val ls = split(name) + if add(tries,ls) : add(errors,IsPrefix(name)) + name sinfo! = info(s) map(check-name,s) map(check-high-form-t,s) @@ -391,6 +363,10 @@ defn IndexOnNonVector (info:FileInfo) : PassException $ string-join $ [info ": [module " mname "] Index illegal on non-vector type."] +defn AccessIndexNotUInt (info:FileInfo) : + PassException $ string-join $ + [info ": [module " mname "] Access index must be a UInt type."] + defn IndexNotUInt (info:FileInfo) : PassException $ string-join $ [info ": [module " mname "] Index is not of UIntType."] @@ -435,9 +411,29 @@ defn OpNotAllSameType (info:FileInfo, op:Symbol) : PassException $ string-join $ [info ": [module " mname "] Primop " op " requires all operands to have the same type."] -defn NodeGroundType (info:FileInfo) : +defn NodePassiveType (info:FileInfo) : + PassException $ string-join $ + [info ": [module " mname "] Node must be a passive type."] + +defn MuxSameType (info:FileInfo) : + PassException $ string-join $ + [info ": [module " mname "] Must mux between equivalent types."] + +defn MuxPassiveTypes (info:FileInfo) : + PassException $ string-join $ + [info ": [module " mname "] Must mux between passive types."] + +defn MuxCondUInt (info:FileInfo) : + PassException $ string-join $ + [info ": [module " mname "] A mux condition must be of type UInt."] + +defn ValidIfPassiveTypes (info:FileInfo) : PassException $ string-join $ - [info ": [module " mname "] Node must be a ground type."] + [info ": [module " mname "] Must validif a passive type."] + +defn ValidIfCondUInt (info:FileInfo) : + PassException $ string-join $ + [info ": [module " mname "] A validif condition must be of type UInt."] ;---------------- Helper Functions -------------- defmethod equal? (t1:Type,t2:Type) -> True|False : @@ -505,9 +501,9 @@ defn check-types-primop (e:DoPrim, errors:Vector<PassException>,info:FileInfo) - NEQUAL-OP : false EQUIV-OP : all-same-type(args(e)) NEQUIV-OP : all-same-type(args(e)) - MUX-OP : - all-same-type(tail(args(e))) - is-uint(head(args(e))) + ;MUX-OP : + ; all-same-type(tail(args(e))) + ; is-uint(head(args(e))) PAD-OP : false AS-UINT-OP : false AS-SINT-OP : false @@ -517,20 +513,31 @@ defn check-types-primop (e:DoPrim, errors:Vector<PassException>,info:FileInfo) - SHIFT-RIGHT-OP : false CONVERT-OP : false NEG-OP : false - BIT-NOT-OP : all-same-type(args(e)) - BIT-AND-OP : all-same-type(args(e)) - BIT-OR-OP : all-same-type(args(e)) - BIT-XOR-OP : all-same-type(args(e)) - BIT-SELECT-OP : false - BITS-SELECT-OP : false - BIT-AND-REDUCE-OP : all-uint(args(e)) - BIT-OR-REDUCE-OP : all-uint(args(e)) - BIT-XOR-REDUCE-OP : all-uint(args(e)) - CONCAT-OP : all-uint(args(e)) + BIT-NOT-OP : all-same-type(args(e)) ;can be either uint or sint + BIT-AND-OP : all-same-type(args(e)) ;can be either uint or sint + BIT-OR-OP : all-same-type(args(e)) ;can be either uint or sint + BIT-XOR-OP : all-same-type(args(e)) ;can be either uint or sint + BIT-SELECT-OP : false ;can be either uint or sint + BITS-SELECT-OP : false ;can be either uint or sint + BIT-AND-REDUCE-OP : false ;can be either uint or sint + BIT-OR-REDUCE-OP : false ;can be either uint or sint + BIT-XOR-REDUCE-OP : false ;can be either uint or sint + CONCAT-OP : false ;can be either uint or sint ;----------------- Check Types Pass --------------------- public defn check-types (c:Circuit) -> Circuit : val errors = Vector<PassException>() + defn passive? (t:Type) -> True|False : + match(t) : + (t:UIntType|SIntType) : true + (t:VectorType) : passive?(type(t)) + (t:BundleType) : + var p? = true + for x in fields(t) do : + if (flip(x) == REVERSE) : p? = false + if not passive?(type(x)) : p? = false + p? + (t) : true defn check-types-e (info:FileInfo,e:Expression) -> Expression : match(map(check-types-e{info,_},e)) : (e:WRef) : e @@ -549,7 +556,18 @@ public defn check-types (c:Circuit) -> Circuit : match(type(exp(e))) : (t:VectorType) : false (t) : add(errors,IndexOnNonVector(info)) + match(type(index(e))) : + (t:UIntType) : false + (t) : add(errors,AccessIndexNotUInt(info)) (e:DoPrim) : check-types-primop(e,errors,info) + (e:Mux) : + if type(tval(e)) != type(fval(e)) : add(errors,MuxSameType(info)) + if not passive?(type(e)) : add(errors,MuxPassiveTypes(info)) + if not passive?(type(e)) : add(errors,MuxPassiveTypes(info)) + if not (type(cond(e)) typeof UIntType) : add(errors,MuxCondUInt(info)) + (e:ValidIf) : + if not passive?(type(e)) : add(errors,ValidIfPassiveTypes(info)) + if not (type(cond(e)) typeof UIntType) : add(errors,ValidIfCondUInt(info)) (e:UIntValue|SIntValue) : false e @@ -590,8 +608,8 @@ public defn check-types (c:Circuit) -> Circuit : (s:Conditionally) : if type(pred(s)) != ut() : add(errors,PredNotUInt(info(s))) (s:DefNode) : - if not type(value(s)) typeof UIntType|SIntType : - add(errors,NodeGroundType(info(s))) + if not passive?(type(value(s))) : + add(errors,NodePassiveType(info(s))) (s) : false s }() @@ -647,12 +665,20 @@ public defn check-genders (c:Circuit) -> Circuit : defn check-gender (info:FileInfo,genders:HashTable<Symbol,Gender>,e:Expression,desired:Gender) -> False : val gender = get-gender(e,genders) val kind* = get-kind(e) - val flip? = - match(type(e)) : - (t:BundleType) : - for f in fields(t) any? : flip(f) == REVERSE - (t) : false + defn flip? (t:Type) -> True|False : + var f? = false + defn flip-rec (t:Type,f:Flip) -> Type : + match(t) : + (t:BundleType) : + for field in fields(t) do : + flip-rec(type(field),f * flip(field)) + (t:VectorType) : flip-rec(type(t),f) + (t) : if f == REVERSE : f? = true + t + flip-rec(t,DEFAULT) + f? + val has-flip? = flip?(type(e)) ;println(e) ;println(gender) ;println(desired) @@ -663,7 +689,7 @@ public defn check-genders (c:Circuit) -> Circuit : [MALE, FEMALE] : add(errors,WrongGender(info,to-symbol(e),as-srcsnk(desired),as-srcsnk(gender))) [FEMALE, MALE] : - if (kind* == PortKind() or kind* == InstanceKind()) and flip? == false : + if (kind* == PortKind() or kind* == InstanceKind()) and has-flip? == false : ; OK! false else : @@ -682,6 +708,8 @@ public defn check-genders (c:Circuit) -> Circuit : (e:DoPrim) : MALE (e:UIntValue) : MALE (e:SIntValue) : MALE + (e:Mux) : MALE + (e:ValidIf) : MALE defn check-genders-e (info:FileInfo,e:Expression,genders:HashTable<Symbol,Gender>) -> False : do(check-genders-e{info,_,genders},e) @@ -693,6 +721,8 @@ public defn check-genders (c:Circuit) -> Circuit : (e:DoPrim) : for e in args(e) do : check-gender(info,genders,e,MALE) + (e:Mux) : do(check-gender{info,genders,_,MALE},e) + (e:ValidIf) : do(check-gender{info,genders,_,MALE},e) (e:UIntValue) : false (e:SIntValue) : false @@ -706,7 +736,7 @@ public defn check-genders (c:Circuit) -> Circuit : (s:DefNode) : check-gender(info(s),genders,value(s),MALE) genders[name(s)] = MALE - (s:DefMemory) : genders[name(s)] = FEMALE + (s:DefMemory) : genders[name(s)] = MALE (s:WDefInstance) : genders[name(s)] = MALE (s:Connect) : check-gender(info(s),genders,loc(s),FEMALE) @@ -725,8 +755,7 @@ public defn check-genders (c:Circuit) -> Circuit : (s:Stop) : check-gender(info(s),genders,en(s),MALE) check-gender(info(s),genders,clk(s),MALE) - (s:Begin) : false - + (s:Begin|IsInvalid) : false for m in modules(c) do : mname = name(m) |
