+
+Types have a per-module namespace.
+This is pre-populated with
+ int i8 i16 uint u8 u64 etc
+ num float f64 f128
+ Bool
+ byte
+ char string
+
+Types can be added with:
+
+ struct name: content
+ record name: content
+ enum name: content
+ class name: content
+
+ name is optional, and can list (parameters) and /attributes
+
+Types can be constructed with
+
+ name(args) parameterized type
+ name^ reference type
+ name[size] array type
+ (args:: args) procedure type
+ (args:: type) function type
+
+
+The content of struct and record are a list of:
+ fieldname: type
+ or
+ fieldname/attribute: type
+
+ 'attribute' can:
+ indicate endianness - bigendian littleendian hostendian
+ 'const' ??
+ identify a refcount,
+ protected by a given lock??
+
+ For enum, content is list of
+ name = value
+ where "= value" is optional
+
+Pointers:
+ to assign a pointer, use foo = stuff
+ to update what the pointer points to, use foo^ = stuff
+ to get a reference to store in a pointer....
+ references are either borrowed or owned.
+ a name defined "type^" is a borrowed reference, a name defined
+ "type@" is owned.
+ borrowed references may be taken of anything, but only remain defined
+ as long as the owner remains defined.
+ owned references can only be taken of ownable objects, and
+ remain indefinitely.
+
+ There are various ways to own an object:
+ - refcount or lock
+ - ownership of a containing object.
+ - ownership provided by class method
+
+non-type names (vars, constants) can be introduced with
+
+const prefix: name = value; ...
+func: name(args::type): statements
+proc: name(args::result): statements
+
+main: statements
+init:
+exit:
+
+
+enum name: values
+
+
+Plan:
+ decide on data structure
+ different types can't really be handled by a big switch now,
+ I probably need and object with function pointers.
+ free_value(), vtype_compat(), val_init(),
+ dup_value(), value_cmp(), print_value(), parse_value()
+
+ parse_value only needed for args - str and num
+ val_init...
+ print_value - only needed for print and code-dump
+ dup_value - needed until pointers can make sense
+ vtype_compat - needed for various things
+ value_cmp - needed until we have object behaviours
+
+ pre-defined
+ Bool
+ int - sizes
+ char
+ string
+ array
+ I think I need to disassociate the type from the storage.
+ So a 'value' is a parsed constant, but something new is needed for
+ the content of a variable.
+ const
+ struct
+
+----------
+
+ I currently have an enum of types that is used to test compatability
+ and for propagation.
+ This needs to change .... I guess I need a struct type* What goes in it?
+ - name
+ - scalar/record/struct/array/pointer/func/enum
+ - other details.
+
+ Do I need forward declarations? Maybe I can just be lazy and
+ require everything to be declared eventually.
+ That isn't sufficient for:
+ - mutually recursive functions
+ - mutually recursive structures
+
+ What about unions ???
+ blend with enum: a tag with fields?
+ struct name:
+ x:int; y:int
+
+ .Bool.true = a:char; b:char
+ .Bool.false = ......
+
+ Are enums just a fancy way of doing 'const'?
+ I could have
+ const: a=1; b=2; c; d
+ which defines module-wide consts.
+ And separately have
+ enum foo: a, b, c
+ which defines consts foo.a foo.b foo.c
+ But I don't really like foo entering the val namespace.
+ If bar:foo, then bar.a could be true/false depending on value of bar.
+ bar.a! could set it?? bar.a=true?
+ var = .foo.a
+
+ How do we allocate new objects?
+ new(type) ???
+ ptrname = new ??
+ new(ptrname)
+ ptrname := new(type)
+
+ Maybe ^= assigns a borrowed reference, and @= assigns an owned reference.
+
+ allocating isn't really a top priority, so I should just focus on
+ non-allocated types.