Arc Forumnew | comments | leaders | submitlogin
3 points by almkglor 6089 days ago | link | parent

Note that a list key is compared using 'iso, not 'is (the quoted list bug notwithstanding)

> There are a few other new things. Most notably, the functional notation for accessing parts of lists/strings/hash tables is now implemented : ('(foo bar baz) 2) returns 'baz.

Cool! How'd you implement it?

I assume it doesn't have support for the 'call* table yet?



3 points by sacado 6089 days ago | link

It looks a little hackish. I implemented it in the END_JUMP macro. If the object in LOCAL(0) (supposed to be a closure) is a string, a table or a cons, perform the adequate lookup operation (taking LOCAL(2) as a parameter). Then perform the actual jump : BEGIN_JUMP, PUSH(LOCAL(1) (which is the continuation)), PUSH(resut of lookup operation), END_JUMP.

call* is not implemented yet.

As for keys in hash tables, I admit I didn't really bother yet. It is quite broken in canonical Arc anyway (and in Anarki too for that matter) : it doesn't work correctly with lists and does not work correctly with strings too (if you update a string key, you're dead). If the hash itself is its own key, it breaks, but I don't know if this is supposed to be feasible or not.

So I'll focus on symbols and numbers as keys, first, as they are the most usual key types anyway, and will gradually introduce other key types.

-----

3 points by almkglor 6089 days ago | link

Just wondering if it's possible to create a bunch of primitives to do the referencing?

  %string-ref
  %list-ref
  %table-ref
Then possibly we could add to lib-ac.scm.arc:

  (= call* (%table)) ;or whatever the table-creating primitive is
  (%sref-table call* 'string
    (fn (s i) (%string-ref s i)))
  (%sref-table call* 'list
    (fn (s i) (%list-ref s i)))
  (%sref-table call* 'table
    (fn (s i) (%table-ref s i)))
  ; for compatibility with existing Anarki
  (set ref
    (fn (c i)
      (if (%is (%type c) 'string)
          (%string-ref c i)
          (if (%is (%type c) 'list)
              (%list-ref c i)
              (if (%is (%type c) 'table)
                  (%table-ref c i)
                  ; dummy stub for error message, when
                  ; errors are implemented
                  ())))))
Then maybe change code-execute* to something like:

  obj fn = SYM2OBJ("fn");
  obj typ;
  goto initjump;
  jump:
  // most common case, so check it first
  if((typ = type(LOCAL(0))) == fn){
    goto realjump;
  } else {
    memmove(&LOCAL(3),&LOCAL(2), (num_args - 2)*sizeof(obj));
    ++num_args;
    LOCAL(2) = LOCAL(0);
    LOCAL(0) = table_lookup(GLOBAL(CALL_TABLE), typ);
    //possibly add a check here to see if it's a function
  }
  realjump:
  pc = LOCAL(0)[0]; //or whichever it should be
  initjump:
  switch(pc){
    ...

-----

1 point by sacado 6089 days ago | link

good idea, I'll implement that soon...

-----