]> ocean-lang.org Git - ocean-D/commitdiff
updates
authorNeilBrown <neil@brown.name>
Tue, 9 Nov 2021 07:53:40 +0000 (18:53 +1100)
committerNeilBrown <neil@brown.name>
Tue, 9 Nov 2021 07:53:40 +0000 (18:53 +1100)
00-TODO
Blog-pointers
Ocean-functions
Ocean-operators
Ocean-references [new file with mode: 0644]

diff --git a/00-TODO b/00-TODO
index 5675fdb226b41beb48c4ba1f0111494811589e7c..ac474b28506bfa2ff427392fd1a5c566284d59d6 100644 (file)
--- a/00-TODO
+++ b/00-TODO
@@ -23,7 +23,6 @@ Current version (Cataract Creek)
      << >> #
      bit-ops & | ~ &~
      op=
-- split values so I can have an array of just the value (1 byte for u8)
 - integers, unsigned, bitfield, float, double?
 - pointers
    - owned or borrowed
@@ -36,7 +35,6 @@ Current version (Cataract Creek)
 
 - allow "do stuff" as a stand-alone statement (scope)
 - 'use' labels *must* appear in case statements.
-- re-read parsergen lit-doc and make sure it is still coherent.
 
 Next version (Govetts Creek):
 - functions and procedures
index 372efc66b0ef889252e5f4fd610b9db42dff06ae..2539232ddae05443b331b93e01e327ac716f7311 100644 (file)
@@ -167,7 +167,7 @@ Rust uses smart pointers to implement
  others.
 It even has Box<> to create on heap instead of stack.
 
-Why doesn't I just do that?  Partly because I don't have classes yet!!
+Why don't I just do that?  Partly because I don't have classes yet!!
 
 I like a simple syntax to test if a pointer is over-loaded.
    if pointer?
@@ -241,3 +241,30 @@ or better
 
   fun foo<x:thing>(a:x, b:x) : x
 
+------------------------
+Years later - March 2021
+
+I need somewhere to start so I need to be able to ignore lots of this detail.
+So in the first instance all references are counted references.  They must refer
+to a struct that contains 'refcount'.
+
+A reference is declared with
+   name : ref base-type
+and the base object can be accessed with
+   name.ref
+though this can sometimes be inferred from "name".
+In particular
+   name.foo
+will find 'foo' either as an attribute of name, or of what name refers to.
+If name refers to a reference, this recurses.
+
+A ref can be checked with "name.valid"
+
+A new object can be allocated with "name.new()", which returns the ref.
+So "name.new().valid" is true if the allocation succeeded, which is always
+will on Linux.
+
+Future ideas might include:
+  type name : ref(attr,list) basetype
+where attr,list can include borrow,counted,single, etc
+
index 9014d1adc9b26d9d057c3d6d9361046db713acc8..50834001635905cb15e345b353f972f39ea1f280 100644 (file)
@@ -1,8 +1,9 @@
-I want to add functions and procedures soon.  I should decide on syntax at least.
+I want to add functions and procedures soon.  I should decide on syntax
+at least.
 
-The args to a function are effective a struct, so I want it to look the same.
-C doesn't allow "int a, b, c" in the parameters, which I think is clumsy.
-struct can be
+The args to a function are effectively a struct, so I want it to look
+the same.  C doesn't allow "int a, b, c" in the parameters, which I
+think is clumsy.  struct can be
 
   struct name:
      a,b,c:number
@@ -13,7 +14,7 @@ So function might be
    func name:
        arg1, arg2: type
        arg3: type2
-   returns type
+   return type
    do:
        stuff
 
@@ -22,16 +23,82 @@ it has a return structure.  So many C functions have 'ret' or 'result'
 variable that it might be nice to follow the Pascal approach of
 assigning to the function name??  or having
 
-    func name:
+    func name
        args:types
-    returns:
+    return
        results:types
-    do:
+    do
        statements
 
 A shorter version would be
 
     func name(args:types;args:types):type { }
 or
-    proc name(args:types;args:types):(result:type;...) {}
+    func name(args:types;args:types):(result:type;...) {}
 
+
+Can arguments be optional?
+ - yes, if "= value" follows the type
+Can we have variable number of args
+ - yes. Any arg can be an inline-array. The last arg can
+   have undefined length [].
+Can named args be passed in
+ - yes, once I have a syntax for manifest structs
+   
+Arrays seem very different from structs.
+ - they don't have names (as types)
+ - they don't need grouping in function params??
+Does this make any sense?
+Maybe I should require the grouping
+  printf("%d %d %d", (1,2,3))
+??
+
+
+Functions can be used before being declared - analysis happens after all is read.
+
+'main' is given an array of strings of unknown length.
+So I need the formal parameter to accept variable-length arrays.
+Do I use
+   argv:[] string
+and support "argv.len", or do I use
+   argv:[argc] string
+which instantiates argc with the length?
+Probably the latter.
+
+Arrays have to be passed by reference, they are const if :: used for type.
+Structs .. ditto.
+Strings and numbers are immutable.
+
+So I need functions to turn strings into number or bool.
+Just bool() and number() for now.
+So
+DONE 1/ change 'program' to make everything a string, and use functions to get numbers.
+DONE 2/ change 'program' to receive an array with bindably size
+DONE 3/ change 'program' to 'func main' etc
+DONE4/ allow more functions.
+
+What syntax to use for formal types?
+I will need type parameterisation some day.  For now I just need the
+size of an array to be parameterised.
+  argv:[argc]string
+looks like normal type.  But it isn't clear if argc is a global constant
+or a variable.
+  argv:[argc:int]string
+seem redunant because of course the array index is an int.
+  argv:[argc:]string
+might be acceptable.
+It is like leaving out the type is
+   a := 4
+
+So let's go with that.
+
+
+DONE To handle functions, and recursion in particular, I need a concept of a
+stack frame in the interpreter.  This needs to include room for
+parameters and results and local variables.  So a function needs to know
+the size of its frame, and each variable needs an offset.
+So I need to switch 'program' over to this approach before adding
+functions.
+Then the function frame will have a results frame separate from the
+main frame, as it can last longer.  So each variable needs to be marked
+as 'result' or not.
index d70058b19df36c9832cc463ab6f9b2cd4bf8aeeb..a2b1ef90788d1d53ef0992c203daf51a927394eb 100644 (file)
@@ -9,7 +9,7 @@ I might want:
 
  Binary: and then, or else, integer division
  Prefix: int
- Suffix: dereference
+ Suffix: dereference (ref)
 
 
  Do I want  COND ? IFTRUE : IFFALSE
@@ -59,7 +59,7 @@ I might want:
       a @@= b
    does a deep copy
 
-What types do operators act one?
+What types do operators act on?
 
    numbers  + - * / %
    bitsets  & | ~ &~
@@ -123,3 +123,43 @@ But ... what syntax do I want for test-and-set?  More genericly cmpxchg.
 An operator that modifies a variable is something I wanted to avoid.
   var ? oldval = newval
 could 'use false' if it fails.
+
+# decided so far:
+
+  +            addition or abs value
+  -            subtraction or negation
+  *            multiply
+  /            div
+  %            remainder
+  ++           catentate
+  ()           group
+  if else      conditional
+  and, or, not  Boolean
+  and then     Boolean
+  or else      Boolean
+  =             assignment
+  :             type
+  < > != == <= >=  comparison
+  [ ]           array access
+  .             field access
+  " ' `         quoting
+  , ;           list
+  {  }          grouping
+
+# expect
+  &            bit and
+  |            bit or
+  &^           bit subtract
+  ^            bit invert (prefix or infix)
+  #             1<< (prefix)
+  << >>         shift
+
+  += -= *= /= %= ++= &= |= &^= ^=
+        What about boolean? and=?
+        if c: a=True // if not c: a=False
+  
+# undecided
+  ?  !  @ $ \ ~
+  -- ** @@ ^^
+
+  Equiv of "a ?: b".  i.e. a if a else b.  Only works if non-Bools can be tested.
diff --git a/Ocean-references b/Ocean-references
new file mode 100644 (file)
index 0000000..42391e2
--- /dev/null
@@ -0,0 +1,95 @@
+References can be 'owned' or 'borrowed'.
+They can also be 'shared' or 'exclusive'
+And maybe I need 'const' as well??
+
+Borrowed references need to be borrowed from somewhere, and it must be
+clear where.
+- from a caller via function parameter passing
+- from a data structure via a lookup function - if structure is
+  append-only
+- from a lock - which asserts ownership while held
+
+Owned references can be:
+  refcounted - are these borrowed from the refcount?
+  single - there is only ever one owner
+The difference is that 'single' uses zero bits for the refcount.
+So maybe if a structure has a field declared 'refcount' it is 
+refcounted, else it can only be 'single'.
+
+A pointer is declared as
+    name: @type
+Attributes can appear afterwards
+    name: @type owned shared
+
+ownership is transferred using
+     new := *old (??)
+This nulls the variable or marks it invalid.
+An assignment like
+     new : @type = old
+will create a new owned reference and is only permitted for refcounted
+
+Owned references are dropped when they are replaced or go out of scope.
+This results in a dec of refcount and possible a free - or "close" once
+I have objects.
+
+When a reference is borrowed I need to know where it is borrowed from.
+The owner can be some other (complex) object or the call stack.
+It might be some set of objects if we don't know for certain.
+
+
+What are some difficult pointer usages that need clear understanding.
+
+1/ linked lists and trees are easy.  The link is owned.
+2/ double-linked lists have two problems.
+  A/ The 'prev' link cannot be owned - so who is it borrowed from?
+  B/ The tail link back to the header.
+
+The links aren't where the ownership resides.  The ownership resides in
+the total data structure - the list.
+The list - represented by the head - owns the references to all members.
+The pointers are just record keeping.
+
+Pointers *can* store ownership, but they are just one option.
+A function can declare that some ownership is stored or released
+without the language being able to confirm it.
+
+I need to write some code to explore what I want.
+
+A ref is dereferenced with '@', but it can be left off if there is a field
+reference, so "ref@.foo" and "ref.foo" are the same.
+
+ref@new allocates a new object
+ref@valid is true if the ref points to something
+ref@drop drops the ref and invalidates the pointer ??
+
+Maybe
+    foo:@type = @new()
+    foo = @null
+
+    foo?
+
+
+
+----
+I wonder if I want user-defined reference attributes.
+This would require generic support in the language.
+The idea is that the language gurantees some simple properties
+and the code provie the manipulations.
+
+So the "owned" attribute is declared as 'single' meaning it isn't
+copied with the pointer.  However it can be explicitly copied
+by a "get_ref" function which returns an 'owned' flag without consuming one.
+
+Some attributes would be "sticky" meaning they follow a value around.
+"mut" or "ro" would be like this.
+Some fields in an object may only be accessed or changed by a method,
+which may explicitly change flags.
+"ro" might prevent updates, "mut" might permit them, "hidden" might
+prevent all accesses, or "xray" might be needed to see anything.
+
+Attributes could define trigger functions which are called in
+certain circumstances.
+"owned" might call free() when the value goes out of scope without being consumed.
+
+Tracking the connection between "owned" and "borrowed" might be
+tricky.  I need some code to play with.