; 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 (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 (fun method-call (object method & arguments) (let (method_fn (get-value (meta object) method)) (if (= method_fn nil) (println "no method " method) (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 (fun make_constructor (members methods) (eval `(lambda ~members (with-meta [,members] [,(map_with_idx (lambda (i x) [array `'~x (lambda (o) (idx o i))]) members) ,(map (lambda (x) [array `'~(idx x 0) (idx x 1)]) methods)])))) ; object syntax (add_grammar_rule 'form ["obj" 'WS 'atom "\\(" ['optional_WS 'atom] * 'optional_WS "\\)" 'optional_WS "{" 'optional_WS ['atom 'optional_WS 'form 'optional_WS] * "}"] (lambda (_ _ name _ members _ _ _ _ _ methods _) `(set! ~name (make_constructor [,(map (lambda (x) `'~(idx x 1)) members)] [,(map (lambda (x) `['~(idx x 0) ~(idx x 2)]) methods)])))) ; Lambda syntax (add_grammar_rule 'form ["\\|" 'optional_WS [ 'atom 'optional_WS ] * "\\|" 'optional_WS 'form ] (lambda (_ _ params _ _ body) `(lambda (,(map (lambda (x) (idx x 0)) params)) ~body))) ; {} body translated to do and let (add_grammar_rule 'block_member [ 'form ] |x| [x]) (add_grammar_rule 'block_member [ "let" 'optional_WS 'atom 'optional_WS "=" 'optional_WS 'form ] |_ _ name _ _ _ rhs| `(~name ~rhs)) (fun construct_body (is_do current to_add i) (if (> (len to_add) i) (cond (and is_do (= (len (idx to_add i)) 1)) (construct_body true (concat current [(idx (idx to_add i) 0)]) to_add (+ i 1)) (= (len (idx to_add i)) 1) (concat current [(construct_body true [do (idx (idx to_add i) 0)] to_add (+ i 1))]) true (concat current [(construct_body false [let [(idx (idx to_add i) 0) (idx (idx to_add i) 1)] ] to_add (+ i 1))])) current)) (add_grammar_rule 'form ["{" 'optional_WS [ 'block_member 'optional_WS ] * "}"] |_ _ inner _| (construct_body true [do] (map |x| (idx x 0) inner) 0)) ; Call functions with function first, c style (notice no whitespace) (add_grammar_rule 'form [ 'form 'form ] |f ps| (concat [f] ps)) ; fun syntax (add_grammar_rule 'form [ "fun" 'WS 'atom 'optional_WS "\\(" 'optional_WS [ 'atom 'optional_WS ] * "\\)" 'optional_WS 'form ] |_ _ name _ _ _ params _ _ body| `(fun ~name (,(map |x| (idx x 0) params)) ~body)) obj Point( x y ) { add |self other| { Point((+ self.x other.x) (+ self.y other.y)) } sub |self other| { Point((- self.x other.x) (- self.y other.y)) } to_str |self| { str("x: " self.x ", y: " self.y) } } fun say_hi(name) { println("hayo" name) } fun test() { let plus_1 = |x| (+ x 1) let a = 1 let b = plus_1(a) println("some" b) say_hi("Marcus") let p1 = Point(1 2) let p2 = Point(3 4) let p3 = p1.add(p2) let p4 = p1.sub(p2) println("p1:" p1.to_str()) println("p2:" p2.to_str()) println("p3:" p3.to_str()) println("p4:" p4.to_str()) (+ a b) } println("Test result is" test())