Union/Sum types =============== How about allowing multiple `data` blocks with names: For example, in file `Expr.slul`: # Common data data int line int column end data Unary Expr op end data Binary Expr op1 Expr op2 end data IntegerLiteral bool negative uint64 value end data StringLiteral # some kind of duplicate handling is necessary. # maybe there should be a single identifier tree, # and then a subtree if it's a union field. # perhaps use (fieldname,union-index) as the key in the ident tree? String value end func print PrintWriter pw int indent # is this necessary? can't we just assume that all non-functions are # instance variables? # * in that case, maybe typeidents would need to be prefixed? # * or, just require that fields are declared before functions accesses Unary.operand Binary.operand1 Binary.operand2 IntegerLiteral.negative IntegerLiteral.value StringLiteral.value code print_indent pw indent switch this.kind case Unary pw.print "unary(" op.print pw (indent+1) case Binary pw.print "binary(" op1.print pw (indent+1) op2.print pw (indent+1) case IntegerLiteral pw.print "int_literal(" pw.print (switch negative [true "-"] [false ""]) number.to_str case StringLiteral pw.print "string_literal(" pw.string "\"" value.c_string_escape() "\"" end pw.println ")" # it could also be (would look nicer in this case, but if only # printing from one function then it will not align as nicely) ")".println pw # or, have some kind of special coroutine that yields stuff to print? yield "unary(" yield (op.to_str (indent+1)) yield .newline # alternatively, one could simply use different names: pw.print "unary(" op.dump pw (indent+1) # or pw.print "unary(" op.print_to pw (indent+1) end More compact syntax: data int line int column case Unary Expr op case Binary Expr op1 Expr op2 case IntegerLiteral bool negative uint64 value case StringLiteral # some kind of duplicate handling is necessary. # maybe there should be a single identifier tree, # and then a subtree if it's a union field. # perhaps use (fieldname,union-index) as the key in the ident tree? String value end func dump io PrintWriter pw int indent code dump_indent pw indent specific pw.println case Unary pw.print "unary(" op.print pw (indent+1) case Binary pw.print "binary(" op1.print pw (indent+1) op2.print pw (indent+1) case IntegerLiteral pw.print "int_literal(" pw.print (switch negative [true "-"] [false ""]) number.to_str case StringLiteral pw.print "string_literal(" pw.string "\"" value.c_string_escape() "\"" end Keyword ------- * case * only * subtype * when