static Bool = NewBoolType(); static Int = NewIntType(); static Pointer[T] = NewPointerType(T); static Array[T,n] = NewArrayType(T, n); static Tuple[...T] = NewStructType(...T); // // RecordType // static RecordType[ID,F] = NewStructType(...FieldTypes(...F)); FieldTypes(first, ...rest) = (FieldType(...first), ...FieldTypes(...rest)); overload FieldTypes() = (); FieldType(name, type) = type; // // Record // private var recordId = 1; private nextRecordId() { var x = recordId; recordId += 1; return x; } Record(fields) = RecordType[nextRecordId(), fields]; Record?(x) = false; [ID,F] overload Record?(static RecordType[ID,F]) = true; [ID, F] RecordFields(static RecordType[ID,F]) = F; // // fieldRef // procedure fieldRef; [T | Record?(T)] overload fieldRef(x:T, ident) { static F = RecordFields(T); return ref structRef(x, static FieldIndex(ident, static 0, ...F)); } FieldIndex(ident, i, first, ...rest) { var name, type == first; if (name == ident) return i; return FieldIndex(ident, static i+1, ...rest); } overload FieldIndex(ident, i) { error("field not found"); } // // Node[T] // static Node[T] = Record((#value, T), (#next, Pointer[Node[T]]));