Begin object/struct syntax & semantics
This commit is contained in:
@@ -751,7 +751,7 @@ fun main(argc: int, argv: **char): int {
|
||||
var parameter_objects = params[1].get_array_rc()
|
||||
for (var i = 0; i < parameter_objects.get().size; i++;) {
|
||||
if !parameter_objects.get()[i].is_symbol() {
|
||||
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("second param to vau has a not symbol member"))))
|
||||
return make_pair(null<KPEnv>(), KPResult::Err(kpString(str("second param to vau has a not symbol member: ") + pr_str(parameter_objects.get()[i], true))))
|
||||
}
|
||||
var parameter = parameter_objects.get()[i].get_symbol_text()
|
||||
if parameter == "&" {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
; do_helper is basically mapping eval over statements, but the last one is in TCO position
|
||||
; a bit of a hack, using cond to sequence (note the repitition of the eval in TCO position if it's last,
|
||||
; otherwise the same eval in cond position, and wheather or not it returns a truthy value, it recurses in TCO position
|
||||
; otherwise the same eval in cond position, and wheather or not it returns a truthy value, it recurses in TCO position)
|
||||
(fun do_helper (s i se) (cond (= i (len s)) nil
|
||||
(= i (- (len s) 1)) (eval (idx s i) se)
|
||||
(eval (idx s i) se) (do_helper s (+ i 1) se)
|
||||
@@ -23,14 +23,30 @@
|
||||
|
||||
(fun vapply (f p ede) (eval (concat [f] p) ede))
|
||||
(fun lapply (f p) (eval (concat [(unwrap f)] p) (current-env)))
|
||||
|
||||
(set! let1 (vau de (s v b) (eval [[vau '_ [s] b] (eval v de)] de)))
|
||||
(set! let (vau de (vs b) (cond (= (len vs) 0) (eval b de) true (vapply let1 [(idx vs 0) (idx vs 1) [let (slice vs 2 -1) b]] de))))
|
||||
|
||||
(set! if (vau de (con than & else) (cond
|
||||
(eval con de) (eval than de)
|
||||
(> (len else) 0) (eval (idx else 0) de)
|
||||
true nil)))
|
||||
(fun map (f l)
|
||||
(let (helper (lambda (f l n i recurse)
|
||||
(if (= i (len l))
|
||||
n
|
||||
(do (set-idx! n i (f (idx l i)))
|
||||
(recurse f l n (+ i 1) recurse)))))
|
||||
(helper f l (array-with-len (len l)) 0 helper)))
|
||||
(fun map_with_idx (f l)
|
||||
(let (helper (lambda (f l n i recurse)
|
||||
(if (= i (len l))
|
||||
n
|
||||
(do (set-idx! n i (f i (idx l i)))
|
||||
(recurse f l n (+ i 1) recurse)))))
|
||||
(helper f l (array-with-len (len l)) 0 helper)))
|
||||
|
||||
(fun print_through (x) (let (_ (println x)) x))
|
||||
(fun print_through (x) (do (println x) x))
|
||||
(fun is_pair? (x) (and (array? x) (> (len x) 0)))
|
||||
|
||||
(set! quasiquote (vau de (x)
|
||||
|
||||
52
method.kp
52
method.kp
@@ -1,9 +1,9 @@
|
||||
; First quick lookup function, since maps are not built in
|
||||
(fun get-value-helper (dict key i) (if (>= i (len dict))
|
||||
nil
|
||||
(if (= key (idx dict i))
|
||||
(idx dict (+ i 1))
|
||||
(get-value-helper dict key (+ i 2)))))
|
||||
(if (= key (idx (idx dict i) 0))
|
||||
(idx (idx dict i) 1)
|
||||
(get-value-helper dict key (+ i 1)))))
|
||||
(fun get-value (dict key) (get-value-helper dict key 0))
|
||||
|
||||
; Our actual method call function
|
||||
@@ -12,16 +12,54 @@
|
||||
(println "no method " method)
|
||||
(do (println "applying" method_fn (concat [object] arguments) ) (lapply method_fn (concat [object] arguments))))))
|
||||
; Some nice syntactic sugar for method calls
|
||||
; No params
|
||||
(add_grammar_rule 'form ['form "\\." 'atom]
|
||||
(lambda (o _ m) `(method-call ~o '~m)))
|
||||
; params
|
||||
(add_grammar_rule 'form ['form "\\." 'atom 'optional_WS "\\(" 'optional_WS 'space_forms 'optional_WS "\\)"]
|
||||
(lambda (o _ m _ _ _ p _ _) `(method-call ~o '~m ,p)))
|
||||
|
||||
; object creation
|
||||
(set! make_object (vau de (name members)
|
||||
(eval (print_through `(fun ~name ~members
|
||||
(with-meta [,members]
|
||||
[,(map_with_idx (lambda (i x) [array `'~x (lambda (o) (idx o i))]) members)]))) de)))
|
||||
|
||||
; object syntax
|
||||
(add_grammar_rule 'form ["obj" 'WS 'atom "\\(" ['optional_WS 'atom] * 'optional_WS "\\)" 'optional_WS "{" "}"] (lambda (_ _ name _ members _ _ _ _ _)
|
||||
`(make_object ~name ~(map (lambda (x) (idx x 1)) members))))
|
||||
|
||||
; Ok, let's create our object by hand for this example
|
||||
(set! actual_obj (with-meta [0] [
|
||||
'inc (lambda (o) (set-idx! o 0 (+ (idx o 0) 1)))
|
||||
'dec (lambda (o) (set-idx! o 0 (- (idx o 0) 1)))
|
||||
'set (lambda (o n) (set-idx! o 0 n))
|
||||
'get (lambda (o) (idx o 0))
|
||||
['inc (lambda (o) (set-idx! o 0 (+ (idx o 0) 1)))]
|
||||
['dec (lambda (o) (set-idx! o 0 (- (idx o 0) 1)))]
|
||||
['set (lambda (o n) (set-idx! o 0 n))]
|
||||
['get (lambda (o) (idx o 0))]
|
||||
]))
|
||||
|
||||
(println "asdf")
|
||||
(println (make_object Wooo ( a b c )))
|
||||
(println "fdsa")
|
||||
|
||||
obj MyConstructor() {}
|
||||
(println '(obj MyConstructor() {}))
|
||||
(println MyConstructor)
|
||||
(println (MyConstructor))
|
||||
|
||||
(println "done with first")
|
||||
|
||||
(println '(obj MyConstructor2( mem1 mem2 ) {}))
|
||||
|
||||
obj MyConstructor2( mem1 mem2 ) {}
|
||||
(println "made")
|
||||
(println MyConstructor2)
|
||||
(println (MyConstructor2 1 2))
|
||||
(println (meta (MyConstructor2 1 2)))
|
||||
(println "it will be " (MyConstructor2 1337 266).mem1())
|
||||
(println "it will be " (MyConstructor2 1337 266).mem2())
|
||||
(println "it will be " (MyConstructor2 1337 777).mem2)
|
||||
(println "it was")
|
||||
|
||||
(do
|
||||
(println (meta actual_obj))
|
||||
; Use our new sugar
|
||||
|
||||
Reference in New Issue
Block a user