2 Types have a per-module namespace.
3 This is pre-populated with
4 int i8 i16 uint u8 u64 etc
10 Types can be added with:
17 name is optional, and can list (parameters) and /attributes
19 Types can be constructed with
21 name(args) parameterized type
24 (args:: args) procedure type
25 (args:: type) function type
28 The content of struct and record are a list of:
31 fieldname/attribute: type
34 indicate endianness - bigendian littleendian hostendian
37 protected by a given lock??
39 For enum, content is list of
41 where "= value" is optional
44 to assign a pointer, use foo = stuff
45 to update what the pointer points to, use foo^ = stuff
46 to get a reference to store in a pointer....
47 references are either borrowed or owned.
48 a name defined "type^" is a borrowed reference, a name defined
50 borrowed references may be taken of anything, but only remain defined
51 as long as the owner remains defined.
52 owned references can only be taken of ownable objects, and
55 There are various ways to own an object:
57 - ownership of a containing object.
58 - ownership provided by class method
60 non-type names (vars, constants) can be introduced with
62 const prefix: name = value; ...
63 func: name(args::type): statements
64 proc: name(args::result): statements
75 decide on data structure
76 different types can't really be handled by a big switch now,
77 I probably need and object with function pointers.
78 free_value(), vtype_compat(), val_init(),
79 dup_value(), value_cmp(), print_value(), parse_value()
81 parse_value only needed for args - str and num
83 print_value - only needed for print and code-dump
84 dup_value - needed until pointers can make sense
85 vtype_compat - needed for various things
86 value_cmp - needed until we have object behaviours
94 I think I need to disassociate the type from the storage.
95 So a 'value' is a parsed constant, but something new is needed for
96 the content of a variable.
97 Also, something new is needed for an intermediate lvalue such as an
98 index to an array or a field in a record. Ths is a type plus a pointer.
99 What about rvalues and the result of a calculation. I guess I store
100 that in a temp location, with a pointer...
102 I need to be clear what "interp_exec()" returns. Conceptually it
103 can be an object of any type, and for procedures it can be a tuple of
104 objects. It needs to identify a type and a value of that type.
105 The "value" might be a reference into a variable, or it might be
106 a copy from a calculation. Eventually the reference will have
107 ownership information
113 0/ when does 1/2 produce an integer? Only when explicitly expected.
114 1/ remove 'tail' from value
116 3/ Add a 'Vtyped' vtype and a 'type' pointer
117 4/ add an owership enum: borrowed, single
118 3/ add a 'void *valref' ??
119 4/ Convert num bool str label to Vtyped
121 No, this is awkward because propagate_types wants a 'type' and this intermediate
122 format has a enum+pointer. So make it just a pointer...
125 Vunknown - NULL pointer
126 Vnone - special value
129 A 'type' must be able to:
130 check is it can convert to some other type, reporting if it wants to
131 convert to another type. This requires visibility into other types.
132 print, compare, parse
133 add subtract multiply divide index
136 I currently have an enum of types that is used to test compatability
138 This needs to change .... I guess I need a struct type* What goes in it?
140 - scalar/record/struct/array/pointer/func/enum
143 Do I need forward declarations? Maybe I can just be lazy and
144 require everything to be declared eventually.
145 That isn't sufficient for:
146 - mutually recursive functions
147 - mutually recursive structures
149 What about unions ???
150 blend with enum: a tag with fields?
154 .Bool.true = a:char; b:char
157 Are enums just a fancy way of doing 'const'?
159 const: a=1; b=2; c; d
160 which defines module-wide consts.
163 which defines consts foo.a foo.b foo.c
164 But I don't really like foo entering the val namespace.
165 If bar:foo, then bar.a could be true/false depending on value of bar.
166 bar.a! could set it?? bar.a=true?
169 How do we allocate new objects?
175 Maybe ^= assigns a borrowed reference, and @= assigns an owned reference.
177 allocating isn't really a top priority, so I should just focus on
182 I need a list of steps again:
184 - look up type by name and add syntax for
191 declares an array of that type/size
192 name : [] = [ 1,2,3 ]
193 declares an array of 3 numbers.
195 extracts an element from the array,
199 creates a slice, which can be stored in a var (borrowed ref) or
203 - new type class which has a size and member type
204 - new type access methods: index and size(?)
206 - new manifest values: [a,b,c] creates an array of whatever member type.
209 struct name : [[ name : type ]]
210 to define a new struct
212 - add syntax to extra a field from a struct
213 how is this type-checked if I don't know the type yet?
215 - add syntax for pointers
217 a:struct foo^ = new()
221 If I declare "struct foo ..." do I use "foo" or "struct foo" to ref the type?
223 So structs, records, enums, and classes must have distinct names.