by henriquegogo on 9/8/22, 4:14 AM with 52 comments
by noelwelsh on 9/8/22, 6:01 AM
by bjarneh on 9/8/22, 7:47 AM
Isn't this very confusing in almost all instances?
by henriquegogo on 9/8/22, 4:14 AM
by camgunz on 9/8/22, 7:01 AM
Anyway again very inspiring :)
by cglong on 9/8/22, 8:10 AM
by qwerty456127 on 9/8/22, 10:12 AM
by melony on 9/8/22, 5:20 AM
by mikewarot on 9/8/22, 5:08 AM
struct KaNode *ka_add(struct KaNode *node, struct KaNode **env) {
if (node->type == KA_STR && node->next->type == KA_STR) {
struct KaNode *output = ka_str(node->str);
strcat(output->str, node->next->str);
return output;
}
return ka_num(node->num + node->next->num);
}
Is this legal? If so, I'm going to use the heck out of it for my version of STOIC.[Edit] Ok.. thanks for the help.. I'm used to seeing function types declared AFTER the parameters because pascal habits die hard. It looked like a run of the mill structure declaration to me.
by andrewshadura on 9/8/22, 7:55 AM
by esjeon on 9/8/22, 2:10 PM
by yafinder on 9/8/22, 11:34 AM
planet = [ name := 'World' nick := 'Earth' ]
'Hello, ' + (planet :: {WAT})
Output: 10585168
by GranularRecipe on 9/8/22, 7:50 AM
by kazinator on 9/9/22, 8:24 AM
$ txr -i kamby.tl
Syntactic toffee recipe: melt butter over low heat, stir in Lisp macros.
1> (kamby-repl)
kmb> (let dz (/ 10 0))
** error: /: division by zero
kmb> (let a 1)
a
kmb> a
1
kmb> (let foo [(let bar1 42) (let bar2 73)])
foo
kmb> foo
#<kamby-env:(bar2 bar1)>
kmb> foo.bar1
42
kmb> foo.bar2
73
kmb> (set a 4)
4
kmb> a
4
kmb> (set a (* 2 a))
** warning: unbound variable a
** error: unbound variable a
Errors out at the end because unknown forms are evaled as Lisp, and Kamby variables are not Lisp variables.Mostly this was to play with the "construct environment tree as-you-go, with qualified pathname access" idea.
Code:
(defstruct kamby-env ()
bindings ;; assoc list
next-env ;; kamby-env object or nil
(:method extend (me sym value)
(upd me.bindings (acons sym value)))
(:method lookup (me sym)
(assoc sym me.bindings))
(:method delete (me sym)
(let ((binding (assoc sym me.bindings)))
(upd me.bindings (remq binding))))
(:method print (me stream pretty-p)
(format stream "#<~s:~s>" 'kamby-env [mapcar car me.bindings])))
(defvar *kamby-env* (new kamby-env))
(defun kamby-error (form fmt . args)
(error `~s: ~s: @fmt` 'kamby-eval (if (atom form) form (car form)) . args))
(defun kamby-eval (form)
(let ((e *kamby-env*))
(match-case form
((let @var @expr) e.(extend var (kamby-eval expr))
var)
((set @var @expr) (let ((binding e.(lookup var)))
(if binding
(rplacd binding (kamby-eval expr))
(kamby-error form "no such variable: ~s" var))
(cdr binding)))
((del @var) (unless e.(delete var)
(kamby-error form "no such variable")))
(@(symbolp @var) (let ((binding e.(lookup var)))
(if binding
(cdr binding)
(kamby-error form "no such variable: ~s" var))))
;; TXR Lisp qref syntax a.b.c.d <--> (qref a b c d)
((qref . @vars) (let (value)
(while vars
(let* ((var (pop vars))
(binding e.(lookup var)))
(unless binding
(kamby-error form "no such variable: ~s (when resolving ~s)" var form))
(set value (cdr binding))
(if (and vars (not (typep value 'kamby-env)))
(kamby-error form "~s isn't an environment object; cannot lookup ~s"
value (car vars)))
(set e value)))
value))
;; TXR Lisp dwim brackets syntax [a b c] <--> (dwim a b c)
((dwim . @forms) (let ((*kamby-env* (new kamby-env next-env e)))
[mapdo kamby-eval forms]
*kamby-env*))
(@else (eval else)))))
(defun kamby-repl ()
(whilet ((line (progn (put-string "kmb> ") (get-line))))
(catch
(prinl (kamby-eval (read line)))
(error (x)
(put-line `** error: @x`)))))
by zubairq on 9/8/22, 4:55 AM
by c3534l on 9/8/22, 4:53 AM