From 7805ff3546f5656ecf55787f58c83f030f953b67 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 18 Nov 2021 22:03:02 +1100 Subject: [PATCH] updates --- 00-TODO | 83 +++++++++++++++++++++++++++----------- Diary | 101 +++++++++++++++++++++++++++++++++++++++++++++++ Ocean-concurrent | 3 +- Ocean-errors | 17 ++++++++ 4 files changed, 180 insertions(+), 24 deletions(-) diff --git a/00-TODO b/00-TODO index 25b8eb1..eafc4ee 100644 --- a/00-TODO +++ b/00-TODO @@ -1,20 +1,44 @@ This is a living document - delete things when done. Avoid discussion. Current version (Cataract Creek) -- functions to return type with 'use' -- functions to return structure with name assignment - bare 'use'? -- '?' prefix operator returns Boolean -- reference to struct (@foo), with @new, @free, @nil -- more number types, no units yet +- _interp_exec() to accept a value*, and type, and only copy large value there. +- functions to return struct with name assignment - bare 'use'? + struct is open-coded in header. Later a similar effect + could be achieved with a named struct marked 'transparent' +- '?' prefix operator returns Boolean, index operator for strings. Can be used to + test for end-of-string +- ?? infix operator return LHS if '?' on it would succeed, else RHS +- reference to struct (@foo), with @new, @free, @nil and ? to test + +Next Version (Govetts Cree) +- int nat cyc {i,n,c}{8,16,32,64} +- # & | ~ &~ - no shift: use (N * #shift) or (N / #shift) +- op= +- enum, with multi-valued names. enum foo { yes, no, many(10) } + bar:foo=.yes; if bar == .no... if ?bar.many: print bar.many, "items" +- set, with bool or int members. set foo { pinned, memalloc, priority(4) } + bar:foo = .memalloc | .priority(2). if bar.pinned: bar.priority += 1 + +Subsequent version +- simple methods. Define "func type.name...." and the name will only be visible + within namespace for type. +- array access to read bytes from strings. How to get length? "?string[4]" ?? +- optional args for functions - if value given +- named args? Needs to look like manifest structs +- array args - last parameter can collect all remaining as array. + +And then +- float64 float32 +- enum as array index. foo:[:enum]int. foo[.baz] = 23 Later - string manipulation -- file i/o -- enum -- basic methods - structs - const fields ... what does that mean? Assign once as initialization? Can be used for array size? What else? + 'const' is wrong word. + I want 'const' for record to be type-wide constants, like enum. I think + These would become read-only. Maybe "init_only" - anonymous field - array or struct (or pointer to these) multiple anon struct are allowed if they don't conflict no - transparent fields! They still have a name, but you can @@ -27,6 +51,9 @@ Later x:content transparent size:number +- static variables. Easy to implement, but need a syntax. Something + really loud. + - manifest values for arrays and structs [a,b,c] or [.foo=a, .bar=b] or [ [1]=a, [2]=b] That last doesn't parse easily, unless we require tags... not a good idea. @@ -37,13 +64,13 @@ Later .foo=a is an expression means a structure with a .foo field assined to 'a' [3] = 2 - is an array for at least 4 elements with 4th set to 2. + is an array of at least 4 elements with 4th set to 2. + Or: an expression that starts '[' is a manifest struct or array. + It contains ',' separate list of assignments. + Each is either ".name = expr" for struct or "expr = expr" for array + Except that would prevent array with enum index. Is that a problem? + -- yet more operators - << >> # - bit-ops & | ~ &~ - op= -- integers, unsigned, bitfield, float, double? - pointers - owned or borrowed - pure, loaded, overloaded, augmented @@ -51,10 +78,14 @@ Later - shared or thread-local - array slice - array buffer - can be added to and grows. -- char, string search, regexp search - allow "do stuff" as a stand-alone statement (scope) - 'use' labels *must* appear in case statements. +- 'then' can extend a case section into some other. + +- expose parse info for editing by code run at compile time. + This allows new attributes to be implemented in app code. + E.g. handling bigendian fields by adding conversion functions. Next version (Govetts Creek): - functions and procedures @@ -74,7 +105,7 @@ Much later - interfaces, inheritance - modules, imports and exports public(version) on types, fields etc -- closures, threads, co-routines, generators +- closures, threads, co-routines, generators lamdas - generics/templates. These should be just a compile-time decision. Same code can be called with suitable methods passed, or recompiled in the new context and then optimised. @@ -84,12 +115,7 @@ Much later measure coverage, adjust based on performance metrics auto-create mock objects Is this just parsing the details in the obj file? -- % formatting -- string / slice / strbuf -- parsing library - sscanf equiv, regexp, LALR - FFI -- GTK -- sockets / http / HTML - parameterised types, and dependant types - message passing primitives - overloading for numbers @@ -101,6 +127,17 @@ Much later - typeswitch? - iso suffixes for number? - foreach? -- case fall-through or go-to -- break/continue or "next","last" +- break/continue or "next","last" - hopefully 'use' is enough - algebraic types + +Library functions: + - UTF8 string disection + - search, regexp + - cvt() interface an format() function + - parsing: rexep? LALR? sscan? + - buffered file IO + - auto-growing buffer including strings + - sockets + - http + - html + - gtk? xcb? \ No newline at end of file diff --git a/Diary b/Diary index daa26f8..c6afd1b 100644 --- a/Diary +++ b/Diary @@ -50,3 +50,104 @@ And a size in bytes? 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. diff --git a/Ocean-concurrent b/Ocean-concurrent index 00d7ea6..7045ed7 100644 --- a/Ocean-concurrent +++ b/Ocean-concurrent @@ -35,11 +35,12 @@ value somehow when the code completes. Having thought about this during my run this morning, my current position is: +(mar 2019??) 1/ we have locking primitives, fields which indicate what lock protects them, and pointers which are typed to say what lock they own. Locks are generally nreader-xor-1writer and spin or wait on a queue, - possibly dedicated, possibly chosed by hash. + possibly dedicated, possibly chosen by hash. a refcount is a lock that is mostly in the nreader state. A 'writer' which frees the object might get queued at object creation. diff --git a/Ocean-errors b/Ocean-errors index b677b86..0141be2 100644 --- a/Ocean-errors +++ b/Ocean-errors @@ -10,3 +10,20 @@ I want things to be able to throw errors - or fail-safe(?) when they aren't caught. I could have an 'else' on any simple statement which does error handling + + +Maybe a type that starts '?' can fail to have a value. + +foo: ?int + + foo = 27/0 + + would not trigger an error, but you need + if ?foo: print foo; else print "div by zero" + to use the value + + Most operators will let an error fall through if it is expected. + + If you want details about the error, you need to declare a type that + holds a value or an error. You then get the error code with foo.err or whatever + you have defined. -- 2.43.0