(args:: args) procedure type
(args:: type) function type
+ I think that for pointer/array constructor, the decoration comes first.
+ foo: [5]int
+ is an array of 5 integers, so foo[5] is an int
+ foo: @bar
+ is an owned pointer to bar, so "foo@" is a bar.
+ foo: @[5]int
+ is an owner pointer to 5 integers while
+ foo:[5]^int
+ is an array of 5 borrowed pointers to integers.
+ Having the result type at the end fits better with the function type.
+ foo:(int, int)string
+ then foo(1,2) returns a string.
+
The content of struct and record are a list of:
fieldname: type
- Add arrays:
name : type[size]
+ e.g. int[4] or foo@[3]
+ What is int[5][20] ?? it is an array of int[5], which is backwards.
+ So maybe I want [5][20]int ??
declares an array of that type/size
name : [] = [ 1,2,3 ]
declares an array of 3 numbers.
If I declare "struct foo ..." do I use "foo" or "struct foo" to ref the type?
I think just "foo".
So structs, records, enums, and classes must have distinct names.
+
+ When do I differentiate between compile-time constants and run-time values?
+ When declaring an array, do I require the size to be constant?
+ In a struct I do ... at time of declaration I calculate the size.
+ For foo:[sqr(a)]int
+ I do that too - and it is at run-time.
+ So during parsing, I need to describe the array with a member-type and executable size.
+ When that is evaluated, a type is created.
+ So we really need an executable which returns a type.
+ But ... we need to know the type when doing type analysis. So while variable size
+ is OK, the compiler needs to know what it is. Maybe the size needs to be a constant, as in
+ a names assiged with "size ::= 4*5". This gives the compiler some chance of comparing
+ types of array - and doing range checking on indexes.
+
+ We currently call var_init to set the type of a variable during type
+ analysis - which makes sense.
+ But for an array we don't have the final type until run-time. So we need an
+ intermediate type.
+ So (for now) the size of an array is either a NUMBER or an IDENTIFIER which must be a
+ constant var.
+ I need a point where the type is instantiated - where the variable is evaluated
+ and the size is set. I guess this happens when the 'struct var' is evaluated...
+ no, when a Declare binode is evaluated.
+
+ What happens if I have
+ a:[foo]number = thing
+ I guess the type analysis needs to afirm that thing has the correct type,
+ then a doesn't need to be initialized.
+
+ If I find
+ a[4] = "hello"
+ and 'a' hasn't been declared .... obviously an error.
+
+ When/what/how.
+ For field access, I need to know the type of the variable.
+ But I can delay the look up until type analysis.
+ So a[4] is Index(a, 4) - a binode
+ a.foo is Field(a, "foo") - need a new exec type - Fieldname
+ a(args) is Call(a, args) - need a new Binode type - Tuple.
+
+So I have to delay 'const' assessment to later too.
+
+----------
+Where do type definition go?
+I don't think they go with statements, they belong separately.
+I don't want the full separation of a "type" section like Pascal
+So they probably go at the top level, equivalent to "program" - and before.
+They start with "struct" or "enum" or "record" etc.
+
+So: what about constants? These are currently statements and so affect a scope in time.
+But for declaring arrays in structs, or initial values of fields, we might want constants.
+A constant could be within a struct, but only that it too limiting. I need module-wide
+constants.
+So I guess:
+
+ const:
+ name ::= value
+ name ::= value
+
+or
+ const { name ::= value ; name ::= value }
+
+--------------
+I'm in the middle of stage-1 on structures.
+
+I need a type to parse the declaration into. It needs to be a linked list
+of fields, each of which is a type, a name, and an initial value. i.e. a 'struct field'.