aboutsummaryrefslogtreecommitdiff
path: root/src/main/stanza/errors.stanza
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/stanza/errors.stanza')
-rw-r--r--src/main/stanza/errors.stanza227
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)