]> ocean-lang.org Git - ocean-D/blob - Ocean-types
updates
[ocean-D] / Ocean-types
1
2 Types have a per-module namespace.
3 This is pre-populated with
4   int i8 i16 uint u8 u64 etc
5   num float f64 f128
6   Bool
7   byte
8   char string
9
10 Types can be added with:
11
12   struct name: content
13   record name: content
14   enum name: content
15   class name: content
16
17  name is optional, and can list (parameters) and /attributes
18
19 Types can be constructed with
20
21    name(args)   parameterized type
22    name^        reference type
23    name[size]   array type
24    (args:: args)  procedure type
25    (args:: type)    function type
26
27
28 The content of struct and record are a list of:
29    fieldname: type
30  or
31    fieldname/attribute: type
32
33  'attribute' can:
34       indicate endianness - bigendian littleendian hostendian
35       'const' ??
36       identify a refcount,
37       protected by a given lock??
38
39  For enum, content is list of
40    name = value
41  where "= value" is optional
42
43 Pointers:
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
49      "type@" is owned.
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
53      remain indefinitely.
54
55    There are various ways to own an object:
56     - refcount or lock
57     - ownership of a containing object.
58     - ownership provided by class method
59
60 non-type names (vars, constants) can be introduced with
61
62 const prefix: name = value; ...
63 func: name(args::type): statements
64 proc: name(args::result): statements
65
66 main: statements
67 init:
68 exit:
69
70
71 enum name: values
72
73
74 Plan:
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()
80
81         parse_value only needed for args - str and num
82         val_init...
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
87
88   pre-defined
89      Bool
90      int - sizes
91      char
92      string
93   array
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...
101
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
108   const
109   struct
110
111
112 Steps:
113  0/ when does 1/2 produce an integer?  Only when explicitly expected.
114  1/ remove 'tail' from value
115  2/ define a 'type'.
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
120
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...
123 What do I do with
124   Vnolabel - rule flag
125   Vunknown   - NULL pointer
126   Vnone  - special value
127
128
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
134 ----------
135
136  I currently have an enum of types that is used to test compatability
137  and for propagation.
138  This needs to change .... I guess I need a struct type* What goes in it?
139   - name
140   - scalar/record/struct/array/pointer/func/enum
141   - other details.
142
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
148
149  What about unions ???
150    blend with enum: a tag with fields?
151    struct name:
152      x:int; y:int
153
154      .Bool.true = a:char; b:char
155      .Bool.false = ......
156
157  Are enums just a fancy way of doing 'const'?
158  I could have
159    const: a=1; b=2; c; d
160  which defines module-wide consts.
161  And separately have
162    enum foo: a, b, c
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?
167    var = .foo.a
168
169  How do we allocate new objects?
170    new(type) ???
171    ptrname = new ??
172    new(ptrname)
173    ptrname := new(type)
174
175  Maybe ^= assigns a borrowed reference, and @= assigns an owned reference.
176
177  allocating isn't really a top priority, so I should just focus on
178  non-allocated types.
179
180
181 -----
182 I need a list of steps again:
183
184  - look up type by name and add syntax for
185       name : type = value
186    and
187       name : type
188
189  - Add arrays:
190       name : type[size]
191     declares an array of that type/size
192       name : [] = [ 1,2,3 ]
193     declares an array of 3 numbers.
194       name[1]
195     extracts an element from the array,
196       name[2] = 4
197     updates an element
198       name[4:5]
199     creates a slice, which can be stored in a var (borrowed ref) or
200     assigned to
201
202     This requires:
203      - new type class which has a size and member type
204      - new type access methods: index and size(?)
205      - new syntax
206      - new manifest values: [a,b,c] creates an array of whatever member type.
207
208  - add syntax for
209       struct name : [[ name : type ]]
210    to define a new struct
211
212  - add syntax to extra a field from a struct
213         how is this type-checked if I don't know the type yet?
214
215  - add syntax for pointers
216      a:= new(struct foo)
217      a:struct foo^ = new()
218
219 -------
220 Questions:
221   If I declare "struct foo ..." do I use "foo" or "struct foo" to ref the type?
222   I think just "foo".
223   So structs, records, enums, and classes must have distinct names.