06oct2020 I want to have a language where '//' is a token - integer division. I want three options in scanner: 1/ parse the comment and report it as a token 2/ parse the comment and don't report it as a token (i.e. 'ignored') 3/ don't parse it, report as TK_mark This could apply separately for "#" and "//" and "/*". But I only have two type: TK_comment and TK_line_comment. I could list these as 'known' but that prevents "///" being recognised as a mark. 12mar2021 How to split values from type so they can be small - only one type pointer for an array, for example. Currently a "value" contains both a 'type' and a union of options: str, num, bool, label, array(recursive), structure where some of these include type information. To split this I need to keep type and attach it to a var and pass around with a value. So that value needs to be a pointer to a union? And a size in bytes? 17mar2021 I need to have transient values - registers? - for holding the intermediate result of a computation before assigning to a variable. This is/was 'struct lrval' which was a val and a *lval. Now that a 'struct value' is always a pointer, the 'struct value' can be either the rval or lval, but I need to be able to store content as well - the old 'struct value val'. Maybe I want 'struct value' to still contain the thing (not a pointer) and use 'char ptr[1]' for generic content. 10oct2021 arrays can have a 'const' as the size - and they can be calculated from the current value of variables. So how do we allocate them? In particular, how do we handle them appearing in recursive functions? For variables with a fixed size - known at function-start at least - we can allocate a stack frame for all of them, and the index off the stack frame. I guess var-sized arrays have a pointer in the stack frame, are allocated when they come into scope, and freed when they go out. So I need var-alloc for these to be quite different to other vars All vars need to be initialized when they come into scope, and de-initialized. Currently we initialise or re-initialised when entering scope, and only free when exiting program 13nov2021 With the beginnings of working functions, and the pending introduction of reference, I need to have a clear understand of function parameter passing: by value or by reference. How are complex return values handled? This needs to cover: intrinsics: numbers strings bool etc structs (and records) arrays - of static known size array slices - of runtime-known size references? Are these just intrinsics? Array slices are easy. They cannot be passed in by value, and cannot easily be passed out. So they always are just references. Passing the array-slice by reference - so the pointer and size can be change - makes no sense. Ditto for references - for the same reason. So it is likely best to treat arrays the same way - as slices. So for arrays, slices, and references, we copy in the pointer (and size), and that is all we copy out. For intrinsics we always copy the whole thing. For strings we do that for now, but maybe change later. As they are immutable it doesn't matter much. So that just leave structs. If the function wants a pointer, we take a reference. Otherwise the function gets to take a copy. i.e. always pass structures by reference, but if the function says it wants just the structure, it transparently copies the content. A related question involves arrays in structs. We want a struct to be able to contain an array of fixed size, and also slices - which need to be references. How does this work? struct foo array:[size]member slice:@[size]member Do we allow one array with local-constant size which gets allocated at the end? Do we allow several and hide the math? That all sounds good, but does it work? A case where a ref to a ref is wanted is with linked lists. The insertion point can be in the head, or in a member. To have a function do the insertion, I need to pass a ref to the insertion point, and I don't want 'if head do this, if member do that' code. But nor do I really want to allow references to references. Maybe I required the 'next' pointer to be a struct containing just a reference. This makes it a little bit harder, which might be a good thing. It also makes the syntax cleaner. A ref is always passed by value, a struct is always by ref, but might be copied. Array is always by ref. Returning a struct.... that is more interesting. 15nov2021 I'm trying to make returning a struct work, and I'm confusing myself. I want interp_exec to optionally take a value* into which it can copy a value - but only if the value would otherwise be destroyed. This is because the alternative is to dup into there, and some things cannot be duped. This could be used for - funcalls, where the value is in the stack about to be destroy - anything that produced a temporary value. But the destination needs to be initialised, so it needs to be "->free"d first. So _interp_exec must always be past a dest buffer. It can be a temp in which case type is NULL, else it is a variable and dtype is provided. interp cases can: 1/put a value in rvtype and rv/lrv or 2/put a value in ret or 3/copy value to dest, and leave rvtype and ret.type as NULL. 2,3 are achieved by "ret = _interp_exec(... dest, dtype) I'm over-thinking. Assign can pass in dest/dtype. If an interp cases uses it (only Funcall) it must ->free the var, then copy or dup content into it, and set rvtype to NULL. "use" does not copy to dest, and we don't pass it through blocks. 17nov2021 How to pack local variables into a stack frame. I cannot do it until after analysis as that is when I'll know the type and size. I want to know what can overlap. And I want to know what is in which function. These are essentially the same thing as functions overlap. I already have a 'depth' - and a next_free list. I could assign sequence numbers to scopes and store start/end I want to do a depth-first walk of the scope tree, and reset the offset as I step up. 13dec2021 propagate_types() returns a type, but this isn't really enough. It also receives and sets flags, but these are confused. We need to know: - was there an error - should be give up - was there progress - should we try again - Is Bool a valid alternative to 'type' - attribute of type passed in - Is value and lval - or constlval - attribute of type returned - Can value be calculated at compile time - attribute of type returned. - Can value be memcopied - will be freed if not used. ?? attribute of type returned. -