@@ 0,0 1,311 @@
+
+using import enum
+using import struct
+using import Rc
+using import Array
+using import Map
+using import String
+using import testing
+using import itertools
+
+let Id = u32
+
+let NoId = (Id 0)
+let NoType = NoId
+
+unlet Builtin
+enum Builtin : u32
+ ### Inputs
+
+ # TypeInt 32 false
+ Samplerate
+
+ ### Outputs
+
+ # TypeVector
+ Audio
+
+enum Op : u32
+ None = 0
+
+ ### Types
+
+ # Op.TypeInt NoType <width : i32> <signed : bool>
+ TypeInt
+
+ # Op.TypeBool NoType
+ TypeBool
+
+ # Op.TypeFloat NoType <width : i32>
+ TypeFloat
+
+ # Op.TypeVector NoType <comp-type : Id> <count : i32>
+ TypeVector
+
+ # Op.TypeArray NoType <element-type : Id> <count : i32>
+ TypeArray
+
+ ### Constants
+
+ # Op.ConstantTrue <bool-type : Id>
+ ConstantTrue
+
+ # Op.ConstantFalse <bool-type : Id>
+ ConstantFalse
+
+ # Op.Constant <type : Id> <literal> ...
+ Constant
+
+ # Op.ConstantComposite <type : Id> <constituent : Id> ...
+ ConstantComposite
+
+ # Op.Source <type : Id> <source : Id>
+ Source
+
+ # Op.Sink NoType <value : Id> <target : Id>
+ Sink
+
+struct Node
+ typeId : Id
+ opCode : Op
+ operands : (Array Id)
+
+ fn... append (self, operand : Id)
+ 'append self.operands operand
+ ;
+ case (self, text : String)
+ numbytes := (countof text)
+ let word =
+ fold (word = 0:u32) for i c in (enumerate text)
+ i0 := (i as u32 & 3:u32)
+ word := word | (c as u32 << (i0 * 8:u32))
+ if (i0 == 3:u32)
+ 'append self.operands word
+ 0:u32
+ else word
+ 'append self.operands word
+ ;
+
+ fn __hash (self)
+ h := (hash self.typeId self.opCode)
+ fold (h = h) for operand in self.operands
+ hash h operand
+
+ @@ memo
+ inline __== (cls T)
+ static-if (cls == T)
+ fn (a b)
+ and
+ a.opCode == b.opCode
+ a.typeId == b.typeId
+ (countof a.operands) == (countof b.operands)
+ do
+ for u v in (zip a.operands b.operands)
+ if (u != v)
+ break false
+ else true
+
+ inline __typecall (cls typeId opCode ...)
+ super-type.__typecall cls typeId opCode
+ static-if (va-empty? ...) ()
+ else
+ local ops : (Array Id)
+ va-map
+ inline (value)
+ 'append ops value
+ ...
+ ops
+
+let RcNode = (Rc Node)
+
+struct UVMIRBuilder
+ nodes : (Array RcNode)
+ rnodes :
+ Map RcNode Id
+ fn (rcnode)
+ hash (rcnode as Node)
+
+ inline __typecall (cls)
+ local nodes : (Array RcNode)
+ 'append nodes (RcNode Op.None NoType)
+ super-type.__typecall cls
+ nodes = nodes
+
+ fn... nodeId (self, node : Node)
+ let id = ('getdefault self.rnodes node NoId)
+ if (id == NoId)
+ let node = (Rc.wrap (deref node))
+ let newid = ((countof self.nodes) as Id)
+ 'append self.nodes (copy node)
+ 'set self.rnodes node newid
+ newid
+ else (copy id)
+
+ fn... integerType (self, width : i32, signed : bool)
+ 'nodeId self
+ Node NoType Op.TypeInt
+ width as u32; signed as u32
+
+ fn... floatType (self, width : i32)
+ 'nodeId self
+ Node NoType Op.TypeFloat
+ width as u32
+
+ fn boolType (self)
+ 'nodeId self
+ Node NoType Op.TypeBool
+
+ fn... vectorType (self, compId : Id, count : i32)
+ 'nodeId self
+ Node NoType Op.TypeVector compId (count as u32)
+
+ fn... arrayType (self, elemId : Id, count : i32)
+ 'nodeId self
+ Node NoType Op.TypeVector elemId (count as u32)
+
+ fn... constInt (self, typeId : Id, value : u32)
+ 'nodeId self
+ Node typeId Op.Constant value
+ case (self, value : i32)
+ this-function self ('integerType self 32 true) (value as u32)
+
+ fn... constUInt (self, value : u32)
+ 'constInt self ('integerType self 32 true) value
+
+ fn... constFloat (self, typeId : Id, value : f32)
+ 'nodeId self
+ Node typeId Op.Constant (bitcast value u32)
+ case (self, value : f32)
+ this-function self ('floatType self 32) value
+
+ fn... constBool (self, value : bool)
+ 'nodeId self
+ Node ('boolType self)
+ ? value
+ Op.ConstantTrue
+ Op.ConstantFalse
+
+ fn... constComposite (self, typeId : Id, ...)
+ 'nodeId self
+ Node typeId Op.ConstantComposite ...
+
+ fn... source (self, typeId : Id, sourceId : Id)
+ 'nodeId self
+ Node typeId Op.Source sourceId
+
+ fn... sink (self, node : Id, targetId : Id)
+ 'nodeId self
+ Node NoType Op.Sink node targetId
+
+ fn... getType (self, node : Id)
+ copy ((self.nodes @ node) . typeId)
+ fn... getOp (self, node : Id)
+ copy ((self.nodes @ node) . opCode)
+
+ fn... tostring
+ case (self, nodeId : Id, result : (mutable &String))
+ fn idstr (id)
+ if (id == 0) "none"
+ else
+ "%" .. (tostring id)
+ inline write (...)
+ va-map
+ inline (s)
+ 'append result s
+ ...
+ node := self.nodes @ nodeId
+ write (idstr nodeId) " ="
+ write " " (repr node.opCode)
+ if (node.typeId != NoType)
+ write " " (idstr node.typeId)
+ local idx = 0
+ let operand-count = (countof node.operands)
+ inline readop ()
+ let operand = (node.operands @ idx)
+ idx += 1
+ operand
+ inline write-id ()
+ let operand = (readop)
+ write " " (idstr operand)
+ inline write-i32 ()
+ let operand = (readop)
+ write " " (repr (operand as i32))
+ inline write-f32 ()
+ let operand = (readop)
+ write " " (repr (bitcast operand f32))
+ inline write-bool ()
+ let operand = (readop)
+ write " " (repr (? (operand != 0) true false))
+ switch node.opCode
+ case Op.TypeInt
+ write-i32; write-bool;
+ case Op.TypeFloat
+ write-i32;
+ case Op.TypeVector
+ write-id;
+ write-i32;
+ case Op.Constant
+ switch ('getOp self node.typeId)
+ case Op.TypeInt
+ write-i32;
+ case Op.TypeFloat
+ write-f32;
+ default;
+ case Op.ConstantComposite
+ for i in (range idx operand-count)
+ write-id;
+ default;
+ for i in (range idx operand-count)
+ let operand = (node.operands @ i)
+ write " " ("?0x" .. (hex operand))
+ case (self)
+ local result : String
+ inline write (...)
+ va-map
+ inline (s)
+ 'append result s
+ ...
+ for id in (range 1 (countof self.nodes))
+ this-function self (id as Id) result
+ write "\n"
+ result
+
+static-if main-module?
+ local builder : UVMIRBuilder
+ test
+ ==
+ 'integerType builder 32 false
+ 'integerType builder 32 false
+ test
+ !=
+ 'integerType builder 16 false
+ 'integerType builder 32 false
+
+ #print
+ 'constFloat builder 3.5
+ 'constBool builder false
+ 'constBool builder true
+
+ local node = (Node Op.None NoType)
+ 'append node (String "test")
+
+ let FT = ('floatType builder 32)
+ 'constComposite builder
+ 'vectorType builder FT 4
+ 'constFloat builder FT 1.0
+ 'constFloat builder FT 2.0
+ 'constFloat builder FT 3.0
+ 'constFloat builder FT 4.0
+
+ test
+ ==
+ 'constInt builder
+ 123
+ 'constInt builder
+ 123
+
+ print
+ 'tostring builder
+
+
+;