Compare commits
No commits in common. "f2c9a6248a5d609e4d6dbeb3be7172cc939ae4ee" and "d8025d967f46d823e016e61666189d68c06f90f5" have entirely different histories.
f2c9a6248a
...
d8025d967f
|
@ -3,7 +3,6 @@ EXPR ::=
|
||||||
bool
|
bool
|
||||||
| int
|
| int
|
||||||
| ident
|
| ident
|
||||||
| float
|
|
||||||
| VARDECL
|
| VARDECL
|
||||||
| FUNDECL
|
| FUNDECL
|
||||||
| FUNCALL
|
| FUNCALL
|
||||||
|
|
|
@ -1,30 +1,30 @@
|
||||||
($ a [1 true 2])
|
($ a [1 true 2])
|
||||||
(assert= 1 (ref a 0))
|
(assert-eq? 1 (ref a 0))
|
||||||
(assert= true (ref a 1))
|
(assert-eq? true (ref a 1))
|
||||||
(assert= 2 (ref a 2))
|
(assert-eq? 2 (ref a 2))
|
||||||
|
|
||||||
($ b [[2 4 6] [8 10 12] [14 16 18]])
|
($ b [[2 4 6] [8 10 12] [14 16 18]])
|
||||||
(assert= 12 (ref b 1 2))
|
(assert-eq? 12 (ref b 1 2))
|
||||||
|
|
||||||
(assert= true (empty? []))
|
(assert-eq? true (empty? []))
|
||||||
(assert= false (empty? [1]))
|
(assert-eq? false (empty? [1]))
|
||||||
|
|
||||||
(assert= 7 (head [7 3 1]))
|
(assert-eq? 7 (head [7 3 1]))
|
||||||
(assert= 3 (ref (tail [7 3 1]) 0))
|
(assert-eq? 3 (ref (tail [7 3 1]) 0))
|
||||||
(assert= 1 (ref (tail [7 3 1]) 1))
|
(assert-eq? 1 (ref (tail [7 3 1]) 1))
|
||||||
|
|
||||||
($ (c arr)
|
($ (c arr)
|
||||||
(if (empty? arr)
|
(if (empty? arr)
|
||||||
0
|
0
|
||||||
(+ (head arr) (c (tail arr)))))
|
(+ (head arr) (c (tail arr)))))
|
||||||
|
|
||||||
(assert= 13 (c [2 4 6 1]))
|
(assert-eq? 13 (c [2 4 6 1]))
|
||||||
|
|
||||||
($ d (cons 2 (cons 4 [6])))
|
($ d (cons 2 (cons 4 [6])))
|
||||||
|
|
||||||
(assert= 2 (ref d 0))
|
(assert-eq? 2 (ref d 0))
|
||||||
(assert= 4 (ref d 1))
|
(assert-eq? 4 (ref d 1))
|
||||||
(assert= 6 (ref d 2))
|
(assert-eq? 6 (ref d 2))
|
||||||
|
|
||||||
(assert= 3 (len d))
|
(assert-eq? 3 (len d))
|
||||||
(assert= 4 (len (cons 18 d)))
|
(assert-eq? 4 (len (cons 18 d)))
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
(assert= 6 (: 2 4 6))
|
(assert-eq? 6 (: 2 4 6))
|
||||||
(assert= 9 (: 2 4 (: 3 0 9)))
|
(assert-eq? 9 (: 2 4 (: 3 0 9)))
|
||||||
|
|
||||||
(:
|
(:
|
||||||
($ a 4)
|
($ a 4)
|
||||||
(assert= 4 a)
|
(assert-eq? 4 a)
|
||||||
(set! a 42)
|
(set! a 42)
|
||||||
(assert= 42 a)
|
(assert-eq? 42 a)
|
||||||
|
|
||||||
(:
|
(:
|
||||||
($ a 7)
|
($ a 7)
|
||||||
(assert= 7 a)
|
(assert-eq? 7 a)
|
||||||
(set! a 32)
|
(set! a 32)
|
||||||
(assert= 32 a)
|
(assert-eq? 32 a)
|
||||||
)
|
)
|
||||||
|
|
||||||
(assert= 42 a)
|
(assert-eq? 42 a)
|
||||||
)
|
)
|
|
@ -1,19 +1,19 @@
|
||||||
(assert= false (not true))
|
(assert-eq? false (not true))
|
||||||
(assert= true (not false))
|
(assert-eq? true (not false))
|
||||||
(assert= false (not (not false)))
|
(assert-eq? false (not (not false)))
|
||||||
|
|
||||||
(assert= true (and true true))
|
(assert-eq? true (and true true))
|
||||||
(assert= false (and true false))
|
(assert-eq? false (and true false))
|
||||||
(assert= false (and false true))
|
(assert-eq? false (and false true))
|
||||||
(assert= false (and false false))
|
(assert-eq? false (and false false))
|
||||||
|
|
||||||
(assert= true (and true true true true true))
|
(assert-eq? true (and true true true true true))
|
||||||
(assert= false (and true true true true false))
|
(assert-eq? false (and true true true true false))
|
||||||
|
|
||||||
(assert= true (or true true))
|
(assert-eq? true (or true true))
|
||||||
(assert= true (or true true))
|
(assert-eq? true (or true true))
|
||||||
(assert= true (or true true))
|
(assert-eq? true (or true true))
|
||||||
(assert= false (or false false))
|
(assert-eq? false (or false false))
|
||||||
|
|
||||||
(assert= false (or false false false false false))
|
(assert-eq? false (or false false false false false))
|
||||||
(assert= true (or false false true false false))
|
(assert-eq? true (or false false true false false))
|
|
@ -1,26 +0,0 @@
|
||||||
(assert= 3.2 3.2)
|
|
||||||
(assert= false (eq? 3.7 7.2))
|
|
||||||
(assert= true (ne? 3.7 7.2))
|
|
||||||
|
|
||||||
(assert= 3.1 (+. 1.0 2.1))
|
|
||||||
(assert= -1.1 (-. 1.0 2.1))
|
|
||||||
(assert= 7.8 (*. 5.2 1.5))
|
|
||||||
(assert= 2.5 (/. 5.0 2.0))
|
|
||||||
(assert= 1.25 (%. 10.0 1.75))
|
|
||||||
(assert= 8.0 (^. 2.0 3.0))
|
|
||||||
|
|
||||||
(assert= true (< 1.0 2.0))
|
|
||||||
(assert= false (< 2.0 2.0))
|
|
||||||
(assert= false (< 3.0 2.0))
|
|
||||||
|
|
||||||
(assert= true (<= 1.0 2.0))
|
|
||||||
(assert= true (<= 2.0 2.0))
|
|
||||||
(assert= false (<= 3.0 2.0))
|
|
||||||
|
|
||||||
(assert= true (> 18.0 5.3))
|
|
||||||
(assert= false (> 18.0 18.0))
|
|
||||||
(assert= false (> 18.0 115.3))
|
|
||||||
|
|
||||||
(assert= true (>= 18.0 5.3))
|
|
||||||
(assert= true (>= 18.0 18.0))
|
|
||||||
(assert= false (>= 18.0 115.3))
|
|
|
@ -1,31 +1,31 @@
|
||||||
;; declare lambda
|
;; declare lambda
|
||||||
($ a (-> (x) (* x 2)))
|
($ a (-> (x) (* x 2)))
|
||||||
(assert= 14 (a 7))
|
(assert-eq? 14 (a 7))
|
||||||
|
|
||||||
;; high order function
|
;; high order function
|
||||||
($ b (-> (x y) (x (x y))))
|
($ b (-> (x y) (x (x y))))
|
||||||
(assert= 12 (b a 3))
|
(assert-eq? 12 (b a 3))
|
||||||
|
|
||||||
;; calling function literal
|
;; calling function literal
|
||||||
(assert= 7 ( (-> (x y) (+ x y 1)) 2 4 ))
|
(assert-eq? 7 ( (-> (x y) (+ x y 1)) 2 4 ))
|
||||||
|
|
||||||
;; syntaxic sugar for function declaration
|
;; syntaxic sugar for function declaration
|
||||||
($ (c n) (* 2 n))
|
($ (c n) (* 2 n))
|
||||||
(assert= 18 (c 9))
|
(assert-eq? 18 (c 9))
|
||||||
|
|
||||||
;; inner variable
|
;; inner variable
|
||||||
($ (d x) ($ y 3) (+ x y))
|
($ (d x) ($ y 3) (+ x y))
|
||||||
(assert= 7 (d 4))
|
(assert-eq? 7 (d 4))
|
||||||
|
|
||||||
;; recursivity
|
;; recursivity
|
||||||
($ (e n)
|
($ (e n)
|
||||||
(if (eq? 0 n) 1
|
(if (eq? 0 n) 1
|
||||||
(* n (e (- n 1)))))
|
(* n (e (- n 1)))))
|
||||||
|
|
||||||
(assert= 120 (e 5))
|
(assert-eq? 120 (e 5))
|
||||||
|
|
||||||
;; self keyword
|
;; self keyword
|
||||||
(assert= 720 ((-> (x)
|
(assert-eq? 720 ((-> (x)
|
||||||
(if (eq? x 0)
|
(if (eq? x 0)
|
||||||
1
|
1
|
||||||
(* x (self (- x 1))))) 6))
|
(* x (self (- x 1))))) 6))
|
||||||
|
@ -35,21 +35,21 @@
|
||||||
($ (inner n) (+ n 1))
|
($ (inner n) (+ n 1))
|
||||||
(inner (inner n)))
|
(inner (inner n)))
|
||||||
|
|
||||||
(assert= 3 (f 1))
|
(assert-eq? 3 (f 1))
|
||||||
|
|
||||||
;; return function
|
;; return function
|
||||||
($ (g)
|
($ (g)
|
||||||
($ (inner n) (* 7 n))
|
($ (inner n) (* 7 n))
|
||||||
inner)
|
inner)
|
||||||
|
|
||||||
(assert= 42 ( (g) 6 ))
|
(assert-eq? 42 ( (g) 6 ))
|
||||||
|
|
||||||
;; return lambda
|
;; return lambda
|
||||||
($ (h)
|
($ (h)
|
||||||
(-> (n)
|
(-> (n)
|
||||||
(* 3 (- n 2))))
|
(* 3 (- n 2))))
|
||||||
|
|
||||||
(assert= 15 ( (h) 7 ))
|
(assert-eq? 15 ( (h) 7 ))
|
||||||
|
|
||||||
;; closure
|
;; closure
|
||||||
($ (i init)
|
($ (i init)
|
||||||
|
@ -61,17 +61,17 @@
|
||||||
($ j (i 0))
|
($ j (i 0))
|
||||||
($ k (i 16))
|
($ k (i 16))
|
||||||
|
|
||||||
(assert= 0 (j))
|
(assert-eq? 0 (j))
|
||||||
(assert= 16 (k))
|
(assert-eq? 16 (k))
|
||||||
(assert= 17 (k))
|
(assert-eq? 17 (k))
|
||||||
(assert= 1 (j))
|
(assert-eq? 1 (j))
|
||||||
(assert= 2 (j))
|
(assert-eq? 2 (j))
|
||||||
(assert= 18 (k))
|
(assert-eq? 18 (k))
|
||||||
(assert= 19 (k))
|
(assert-eq? 19 (k))
|
||||||
(assert= 3 (j))
|
(assert-eq? 3 (j))
|
||||||
(assert= 4 (j))
|
(assert-eq? 4 (j))
|
||||||
(assert= 5 (j))
|
(assert-eq? 5 (j))
|
||||||
(assert= 20 (k))
|
(assert-eq? 20 (k))
|
||||||
|
|
||||||
($ m 1)
|
($ m 1)
|
||||||
($ (n)
|
($ (n)
|
||||||
|
@ -84,12 +84,12 @@
|
||||||
($ o (n))
|
($ o (n))
|
||||||
($ p (n))
|
($ p (n))
|
||||||
|
|
||||||
(assert= 2 (o))
|
(assert-eq? 2 (o))
|
||||||
(assert= 4 (o))
|
(assert-eq? 4 (o))
|
||||||
(assert= 6 (o))
|
(assert-eq? 6 (o))
|
||||||
|
|
||||||
(assert= 2 (p))
|
(assert-eq? 2 (p))
|
||||||
(assert= 4 (p))
|
(assert-eq? 4 (p))
|
||||||
(assert= 6 (p))
|
(assert-eq? 6 (p))
|
||||||
|
|
||||||
(assert= 1 m)
|
(assert-eq? 1 m)
|
|
@ -1,5 +1,5 @@
|
||||||
(assert= 7 (if true 7 9))
|
(assert-eq? 7 (if true 7 9))
|
||||||
(assert= 9 (if false 7 9))
|
(assert-eq? 9 (if false 7 9))
|
||||||
|
|
||||||
($ (max x y)
|
($ (max x y)
|
||||||
(if (> x y)
|
(if (> x y)
|
||||||
|
@ -7,5 +7,5 @@
|
||||||
y
|
y
|
||||||
))
|
))
|
||||||
|
|
||||||
(assert= 32 (max 3 32))
|
(assert-eq? 32 (max 3 32))
|
||||||
(assert= 329 (max 329 32))
|
(assert-eq? 329 (max 329 32))
|
||||||
|
|
|
@ -1,47 +1,47 @@
|
||||||
(assert= 7 7)
|
(assert-eq? 7 7)
|
||||||
|
|
||||||
(assert= 0 (+))
|
(assert-eq? 0 (+))
|
||||||
(assert= 3 (+ 3))
|
(assert-eq? 3 (+ 3))
|
||||||
(assert= 5 (+ 2 3))
|
(assert-eq? 5 (+ 2 3))
|
||||||
|
|
||||||
(assert= 0 (-))
|
(assert-eq? 0 (-))
|
||||||
(assert= -3 (- 3))
|
(assert-eq? -3 (- 3))
|
||||||
(assert= -1 (- 2 3))
|
(assert-eq? -1 (- 2 3))
|
||||||
(assert= 5 (- 8 3))
|
(assert-eq? 5 (- 8 3))
|
||||||
|
|
||||||
(assert= 1 (*))
|
(assert-eq? 1 (*))
|
||||||
(assert= 6 (* 3 2))
|
(assert-eq? 6 (* 3 2))
|
||||||
(assert= 120 (* 1 2 3 4 5))
|
(assert-eq? 120 (* 1 2 3 4 5))
|
||||||
|
|
||||||
(assert= 1 (/))
|
(assert-eq? 1 (/))
|
||||||
(assert= 6 (/ 6))
|
(assert-eq? 6 (/ 6))
|
||||||
(assert= 3 (/ 6 2))
|
(assert-eq? 3 (/ 6 2))
|
||||||
(assert= 2 (/ 12 2 3))
|
(assert-eq? 2 (/ 12 2 3))
|
||||||
|
|
||||||
(assert= 1 (%))
|
(assert-eq? 1 (%))
|
||||||
(assert= 3 (% 7 4))
|
(assert-eq? 3 (% 7 4))
|
||||||
(assert= 2 (% 13 7 4))
|
(assert-eq? 2 (% 13 7 4))
|
||||||
|
|
||||||
(assert= 1 (^))
|
(assert-eq? 1 (^))
|
||||||
(assert= 2 (^ 2))
|
(assert-eq? 2 (^ 2))
|
||||||
(assert= 8 (^ 2 3))
|
(assert-eq? 8 (^ 2 3))
|
||||||
(assert= 64 (^ 2 3 2))
|
(assert-eq? 64 (^ 2 3 2))
|
||||||
|
|
||||||
(assert= true (< 5 10))
|
(assert-eq? true (< 5 10))
|
||||||
(assert= false (< 5 5))
|
(assert-eq? false (< 5 5))
|
||||||
(assert= false (< 5 3))
|
(assert-eq? false (< 5 3))
|
||||||
|
|
||||||
(assert= true (<= 5 10))
|
(assert-eq? true (<= 5 10))
|
||||||
(assert= true (<= 5 5))
|
(assert-eq? true (<= 5 5))
|
||||||
(assert= false (<= 5 3))
|
(assert-eq? false (<= 5 3))
|
||||||
|
|
||||||
(assert= true (> 15 10))
|
(assert-eq? true (> 15 10))
|
||||||
(assert= false (> 15 15))
|
(assert-eq? false (> 15 15))
|
||||||
(assert= false (> 15 37))
|
(assert-eq? false (> 15 37))
|
||||||
|
|
||||||
(assert= true (>= 15 10))
|
(assert-eq? true (>= 15 10))
|
||||||
(assert= true (>= 15 15))
|
(assert-eq? true (>= 15 15))
|
||||||
(assert= false (>= 15 37))
|
(assert-eq? false (>= 15 37))
|
||||||
|
|
||||||
(assert= true (ne? 5 8))
|
(assert-eq? true (ne? 5 8))
|
||||||
(assert= false (ne? 5 5))
|
(assert-eq? false (ne? 5 5))
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
($ a 1)
|
($ a 1)
|
||||||
(set! a 2)
|
(set! a 2)
|
||||||
(assert= 2 a )
|
(assert-eq? 2 a )
|
||||||
|
|
||||||
($ (b x) (+ x 1))
|
($ (b x) (+ x 1))
|
||||||
($ (c x) (* x 2))
|
($ (c x) (* x 2))
|
||||||
($ d b)
|
($ d b)
|
||||||
(assert= 3 (d 2))
|
(assert-eq? 3 (d 2))
|
||||||
(set! d c)
|
(set! d c)
|
||||||
(assert= 4 (d 2))
|
(assert-eq? 4 (d 2))
|
204
lib/core.cpp
204
lib/core.cpp
|
@ -267,236 +267,41 @@ extern "C" void lib_int(grino::Loader& loader)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void lib_float(grino::Loader& loader)
|
|
||||||
{
|
|
||||||
loader.add_native("+.", [](auto args){
|
|
||||||
float result = 0;
|
|
||||||
|
|
||||||
for (auto value: args)
|
|
||||||
{
|
|
||||||
result += value->as_float();
|
|
||||||
}
|
|
||||||
|
|
||||||
grino::Loc loc {"???", 0};
|
|
||||||
|
|
||||||
if (args.empty() == false)
|
|
||||||
{
|
|
||||||
loc = args.front()->loc();
|
|
||||||
}
|
|
||||||
|
|
||||||
return grino::Value::make_float(loc, result);
|
|
||||||
});
|
|
||||||
|
|
||||||
loader.add_native("*.", [](auto args){
|
|
||||||
float result = 1;
|
|
||||||
|
|
||||||
for (auto value: args)
|
|
||||||
{
|
|
||||||
result *= value->as_float();
|
|
||||||
}
|
|
||||||
|
|
||||||
grino::Loc loc {"???", 0};
|
|
||||||
|
|
||||||
if (args.empty() == false)
|
|
||||||
{
|
|
||||||
loc = args.front()->loc();
|
|
||||||
}
|
|
||||||
|
|
||||||
return grino::Value::make_float(loc, result);
|
|
||||||
});
|
|
||||||
|
|
||||||
loader.add_native("-.", [](auto args){
|
|
||||||
grino::Loc loc {"???", 0};
|
|
||||||
|
|
||||||
if (args.empty() == false)
|
|
||||||
{
|
|
||||||
loc = args.front()->loc();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return grino::Value::make_float(loc, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
float result = args[0]->as_float();
|
|
||||||
|
|
||||||
if (args.size() == 1)
|
|
||||||
{
|
|
||||||
return grino::Value::make_float(loc, -result);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i=1; i<args.size(); i++)
|
|
||||||
{
|
|
||||||
result -= args[i]->as_float();
|
|
||||||
}
|
|
||||||
|
|
||||||
return grino::Value::make_float(loc, result);
|
|
||||||
});
|
|
||||||
|
|
||||||
loader.add_native("/.", [](auto args){
|
|
||||||
grino::Loc loc {"???", 0};
|
|
||||||
|
|
||||||
if (args.empty() == false)
|
|
||||||
{
|
|
||||||
loc = args.front()->loc();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return grino::Value::make_float(loc, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
float result = args[0]->as_float();
|
|
||||||
|
|
||||||
if (args.size() == 1)
|
|
||||||
{
|
|
||||||
return grino::Value::make_float(loc, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i=1; i<args.size(); i++)
|
|
||||||
{
|
|
||||||
result /= args[i]->as_float();
|
|
||||||
}
|
|
||||||
|
|
||||||
return grino::Value::make_float(loc, result);
|
|
||||||
});
|
|
||||||
|
|
||||||
loader.add_native("%.", [](auto args){
|
|
||||||
grino::Loc loc {"???", 0};
|
|
||||||
|
|
||||||
if (args.empty() == false)
|
|
||||||
{
|
|
||||||
loc = args.front()->loc();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return grino::Value::make_float(loc, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
float result = args[0]->as_float();
|
|
||||||
|
|
||||||
if (args.size() == 1)
|
|
||||||
{
|
|
||||||
return grino::Value::make_float(loc, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i=1; i<args.size(); i++)
|
|
||||||
{
|
|
||||||
result = std::fmod(result, args[i]->as_float());
|
|
||||||
}
|
|
||||||
|
|
||||||
return grino::Value::make_float(loc, result);
|
|
||||||
});
|
|
||||||
|
|
||||||
loader.add_native("^.", [](auto args){
|
|
||||||
grino::Loc loc {"???", 0};
|
|
||||||
|
|
||||||
if (args.empty() == false)
|
|
||||||
{
|
|
||||||
loc = args.front()->loc();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return grino::Value::make_float(loc, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
float result = args[0]->as_float();
|
|
||||||
|
|
||||||
if (args.size() == 1)
|
|
||||||
{
|
|
||||||
return grino::Value::make_int(loc, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i=1; i<args.size(); i++)
|
|
||||||
{
|
|
||||||
result = std::pow(result, args[i]->as_float());
|
|
||||||
}
|
|
||||||
|
|
||||||
return grino::Value::make_float(loc, result);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void lib_cmp(grino::Loader& loader)
|
extern "C" void lib_cmp(grino::Loader& loader)
|
||||||
{
|
{
|
||||||
loader.add_native("<", [](auto args){
|
loader.add_native("<", [](auto args){
|
||||||
if (args[0]->type() == grino::TYPE_INT)
|
|
||||||
{
|
|
||||||
int lhs = args[0]->as_int();
|
int lhs = args[0]->as_int();
|
||||||
int rhs = args[1]->as_int();
|
int rhs = args[1]->as_int();
|
||||||
|
|
||||||
return grino::Value::make_bool(args[0]->loc(), lhs < rhs);
|
return grino::Value::make_bool(args[0]->loc(), lhs < rhs);
|
||||||
}
|
|
||||||
else if (args[0]->type() == grino::TYPE_FLOAT)
|
|
||||||
{
|
|
||||||
float lhs = args[0]->as_float();
|
|
||||||
float rhs = args[1]->as_float();
|
|
||||||
|
|
||||||
return grino::Value::make_bool(args[0]->loc(), lhs < rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
loader.add_native("<=", [](auto args){
|
loader.add_native("<=", [](auto args){
|
||||||
if (args[0]->type() == grino::TYPE_INT)
|
|
||||||
{
|
|
||||||
int lhs = args[0]->as_int();
|
int lhs = args[0]->as_int();
|
||||||
int rhs = args[1]->as_int();
|
int rhs = args[1]->as_int();
|
||||||
|
|
||||||
return grino::Value::make_bool(args[0]->loc(), lhs <= rhs);
|
return grino::Value::make_bool(args[0]->loc(), lhs <= rhs);
|
||||||
}
|
|
||||||
else if (args[0]->type() == grino::TYPE_FLOAT)
|
|
||||||
{
|
|
||||||
float lhs = args[0]->as_float();
|
|
||||||
float rhs = args[1]->as_float();
|
|
||||||
|
|
||||||
return grino::Value::make_bool(args[0]->loc(), lhs <= rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
loader.add_native(">", [](auto args){
|
loader.add_native(">", [](auto args){
|
||||||
if (args[0]->type() == grino::TYPE_INT)
|
|
||||||
{
|
|
||||||
int lhs = args[0]->as_int();
|
int lhs = args[0]->as_int();
|
||||||
int rhs = args[1]->as_int();
|
int rhs = args[1]->as_int();
|
||||||
|
|
||||||
return grino::Value::make_bool(args[0]->loc(), lhs > rhs);
|
return grino::Value::make_bool(args[0]->loc(), lhs > rhs);
|
||||||
}
|
|
||||||
else if (args[0]->type() == grino::TYPE_FLOAT)
|
|
||||||
{
|
|
||||||
float lhs = args[0]->as_float();
|
|
||||||
float rhs = args[1]->as_float();
|
|
||||||
|
|
||||||
return grino::Value::make_bool(args[0]->loc(), lhs > rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
loader.add_native(">=", [](auto args){
|
loader.add_native(">=", [](auto args){
|
||||||
if (args[0]->type() == grino::TYPE_INT)
|
|
||||||
{
|
|
||||||
int lhs = args[0]->as_int();
|
int lhs = args[0]->as_int();
|
||||||
int rhs = args[1]->as_int();
|
int rhs = args[1]->as_int();
|
||||||
|
|
||||||
return grino::Value::make_bool(args[0]->loc(), lhs >= rhs);
|
return grino::Value::make_bool(args[0]->loc(), lhs >= rhs);
|
||||||
}
|
|
||||||
else if (args[0]->type() == grino::TYPE_FLOAT)
|
|
||||||
{
|
|
||||||
float lhs = args[0]->as_float();
|
|
||||||
float rhs = args[1]->as_float();
|
|
||||||
|
|
||||||
return grino::Value::make_bool(args[0]->loc(), lhs >= rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
loader.add_native("ne?", [](auto args){
|
loader.add_native("ne?", [](auto args){
|
||||||
auto lhs = args[0];
|
int lhs = args[0]->as_int();
|
||||||
auto rhs = args[1];
|
int rhs = args[1]->as_int();
|
||||||
|
|
||||||
return grino::Value::make_bool(args[0]->loc(), !lhs->equals(*rhs));
|
return grino::Value::make_bool(args[0]->loc(), lhs != rhs);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,7 +390,7 @@ extern "C" void lib_assert(grino::Loader& loader)
|
||||||
return grino::Value::make_bool(args.front()->loc(), true);
|
return grino::Value::make_bool(args.front()->loc(), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
loader.add_native("assert=", [](auto args){
|
loader.add_native("assert-eq?", [](auto args){
|
||||||
auto lhs = args.front();
|
auto lhs = args.front();
|
||||||
|
|
||||||
for (size_t i=1; i<args.size(); i++)
|
for (size_t i=1; i<args.size(); i++)
|
||||||
|
@ -615,7 +420,6 @@ extern "C" void lib(grino::Loader& loader)
|
||||||
{
|
{
|
||||||
lib_assert(loader);
|
lib_assert(loader);
|
||||||
lib_int(loader);
|
lib_int(loader);
|
||||||
lib_float(loader);
|
|
||||||
lib_cmp(loader);
|
lib_cmp(loader);
|
||||||
lib_bool(loader);
|
lib_bool(loader);
|
||||||
lib_flow_control(loader);
|
lib_flow_control(loader);
|
||||||
|
|
|
@ -145,15 +145,6 @@ namespace grino
|
||||||
program.push_constant(value));
|
program.push_constant(value));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NODE_FLOAT: {
|
|
||||||
std::string repr = node->repr();
|
|
||||||
|
|
||||||
auto value = Value::make_float(node->loc(), std::stof(repr));
|
|
||||||
|
|
||||||
program.push_instr(OPCODE_LOAD_CONST,
|
|
||||||
program.push_constant(value));
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case NODE_VARDECL: {
|
case NODE_VARDECL: {
|
||||||
std::string ident = node->child(0).lock()->repr();
|
std::string ident = node->child(0).lock()->repr();
|
||||||
auto expr = node->child(1).lock();
|
auto expr = node->child(1).lock();
|
||||||
|
|
|
@ -18,7 +18,6 @@ namespace grino
|
||||||
add_keyword(NODE_BOOL, "true", true);
|
add_keyword(NODE_BOOL, "true", true);
|
||||||
add_keyword(NODE_BOOL, "false", true);
|
add_keyword(NODE_BOOL, "false", true);
|
||||||
|
|
||||||
m_scanners.push_back(std::bind(&Lexer::scan_float, this));
|
|
||||||
m_scanners.push_back(std::bind(&Lexer::scan_int, this));
|
m_scanners.push_back(std::bind(&Lexer::scan_int, this));
|
||||||
m_scanners.push_back(std::bind(&Lexer::scan_ident, this));
|
m_scanners.push_back(std::bind(&Lexer::scan_ident, this));
|
||||||
}
|
}
|
||||||
|
@ -259,51 +258,4 @@ namespace grino
|
||||||
repr
|
repr
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ScanInfo> Lexer::scan_float()
|
|
||||||
{
|
|
||||||
size_t cursor = m_cursor;
|
|
||||||
std::string repr;
|
|
||||||
|
|
||||||
if (has_more(cursor) && at(cursor) == '-')
|
|
||||||
{
|
|
||||||
repr += "-";
|
|
||||||
cursor++;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (has_more(cursor)
|
|
||||||
&& std::isdigit(at(cursor)))
|
|
||||||
{
|
|
||||||
repr += at(cursor);
|
|
||||||
cursor++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!has_more(cursor) || at(cursor) != '.')
|
|
||||||
{
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
repr += at(cursor);
|
|
||||||
cursor++;
|
|
||||||
|
|
||||||
while (has_more(cursor)
|
|
||||||
&& std::isdigit(at(cursor)))
|
|
||||||
{
|
|
||||||
repr += at(cursor);
|
|
||||||
cursor++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (repr.empty()
|
|
||||||
|| repr.back() == '-'
|
|
||||||
|| repr.back() == '.')
|
|
||||||
{
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ScanInfo {
|
|
||||||
cursor,
|
|
||||||
NODE_FLOAT,
|
|
||||||
repr
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,6 @@ namespace grino
|
||||||
bool has_value);
|
bool has_value);
|
||||||
|
|
||||||
std::optional<ScanInfo> scan_ident();
|
std::optional<ScanInfo> scan_ident();
|
||||||
std::optional<ScanInfo> scan_float();
|
|
||||||
std::optional<ScanInfo> scan_int();
|
std::optional<ScanInfo> scan_int();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,7 @@
|
||||||
G(NODE_OSQUARE), \
|
G(NODE_OSQUARE), \
|
||||||
G(NODE_CSQUARE), \
|
G(NODE_CSQUARE), \
|
||||||
G(NODE_BLOCK), \
|
G(NODE_BLOCK), \
|
||||||
G(NODE_ARRAY), \
|
G(NODE_ARRAY)
|
||||||
G(NODE_FLOAT)
|
|
||||||
|
|
||||||
namespace grino
|
namespace grino
|
||||||
{
|
{
|
||||||
|
|
|
@ -150,8 +150,7 @@ namespace grino
|
||||||
|
|
||||||
if (type_is(NODE_IDENT)
|
if (type_is(NODE_IDENT)
|
||||||
|| type_is(NODE_BOOL)
|
|| type_is(NODE_BOOL)
|
||||||
|| type_is(NODE_INT)
|
|| type_is(NODE_INT))
|
||||||
|| type_is(NODE_FLOAT))
|
|
||||||
{
|
{
|
||||||
return consume();
|
return consume();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,14 +26,6 @@ namespace grino
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ std::shared_ptr<Value> Value::make_float(Loc const& loc, float val)
|
|
||||||
{
|
|
||||||
auto value = std::make_shared<Value>(loc);
|
|
||||||
value->m_type = TYPE_FLOAT;
|
|
||||||
value->m_float_val = val;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*static*/
|
/*static*/
|
||||||
std::shared_ptr<Value> Value::make_native_function(Loc const& loc,
|
std::shared_ptr<Value> Value::make_native_function(Loc const& loc,
|
||||||
native_t val)
|
native_t val)
|
||||||
|
@ -115,7 +107,6 @@ namespace grino
|
||||||
{
|
{
|
||||||
case TYPE_NIL: return "<nil>";
|
case TYPE_NIL: return "<nil>";
|
||||||
case TYPE_INT: return std::to_string(*m_int_val);
|
case TYPE_INT: return std::to_string(*m_int_val);
|
||||||
case TYPE_FLOAT: return std::to_string(*m_float_val);
|
|
||||||
case TYPE_BOOL: return *m_bool_val ? "true" : "false";
|
case TYPE_BOOL: return *m_bool_val ? "true" : "false";
|
||||||
case TYPE_FUNCTION: return "<function>";
|
case TYPE_FUNCTION: return "<function>";
|
||||||
case TYPE_REF: return "&" + std::to_string(*m_ref_val);
|
case TYPE_REF: return "&" + std::to_string(*m_ref_val);
|
||||||
|
@ -149,8 +140,6 @@ namespace grino
|
||||||
case TYPE_NIL: return true;
|
case TYPE_NIL: return true;
|
||||||
case TYPE_BOOL: return *m_bool_val == *other.m_bool_val;
|
case TYPE_BOOL: return *m_bool_val == *other.m_bool_val;
|
||||||
case TYPE_INT: return *m_int_val == *other.m_int_val;
|
case TYPE_INT: return *m_int_val == *other.m_int_val;
|
||||||
case TYPE_FLOAT:
|
|
||||||
return std::fabs(*m_float_val - *other.m_float_val) < FLOAT_APPROX;
|
|
||||||
case TYPE_REF: return *m_ref_val == *other.m_ref_val;
|
case TYPE_REF: return *m_ref_val == *other.m_ref_val;
|
||||||
case TYPE_PROGRAM: return false;
|
case TYPE_PROGRAM: return false;
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ namespace grino
|
||||||
static std::shared_ptr<Value> make_nil(Loc const& loc);
|
static std::shared_ptr<Value> make_nil(Loc const& loc);
|
||||||
static std::shared_ptr<Value> make_bool(Loc const& loc, bool val);
|
static std::shared_ptr<Value> make_bool(Loc const& loc, bool val);
|
||||||
static std::shared_ptr<Value> make_int(Loc const& loc, int val);
|
static std::shared_ptr<Value> make_int(Loc const& loc, int val);
|
||||||
static std::shared_ptr<Value> make_float(Loc const& loc, float val);
|
|
||||||
static std::shared_ptr<Value> make_native_function(Loc const& loc,
|
static std::shared_ptr<Value> make_native_function(Loc const& loc,
|
||||||
native_t val);
|
native_t val);
|
||||||
static std::shared_ptr<Value> make_function(Loc const& loc,
|
static std::shared_ptr<Value> make_function(Loc const& loc,
|
||||||
|
@ -43,7 +42,6 @@ namespace grino
|
||||||
Loc loc() const { return m_loc; }
|
Loc loc() const { return m_loc; }
|
||||||
TypeType type() const { return m_type; }
|
TypeType type() const { return m_type; }
|
||||||
bool as_bool() const { return *m_bool_val; }
|
bool as_bool() const { return *m_bool_val; }
|
||||||
float as_float() const { return *m_float_val; }
|
|
||||||
int as_int() const { return *m_int_val; }
|
int as_int() const { return *m_int_val; }
|
||||||
std::shared_ptr<Function> as_function() const { return m_function_val; }
|
std::shared_ptr<Function> as_function() const { return m_function_val; }
|
||||||
size_t as_ref() const { return *m_ref_val; }
|
size_t as_ref() const { return *m_ref_val; }
|
||||||
|
@ -59,7 +57,6 @@ namespace grino
|
||||||
TypeType m_type = TYPE_NIL;
|
TypeType m_type = TYPE_NIL;
|
||||||
std::optional<bool> m_bool_val;
|
std::optional<bool> m_bool_val;
|
||||||
std::optional<int> m_int_val;
|
std::optional<int> m_int_val;
|
||||||
std::optional<float> m_float_val;
|
|
||||||
std::shared_ptr<Function> m_function_val;
|
std::shared_ptr<Function> m_function_val;
|
||||||
std::shared_ptr<Program> m_program_val;
|
std::shared_ptr<Program> m_program_val;
|
||||||
std::optional<size_t> m_ref_val;
|
std::optional<size_t> m_ref_val;
|
||||||
|
|
|
@ -16,6 +16,4 @@
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "mutils.hpp"
|
#include "mutils.hpp"
|
||||||
|
|
||||||
#define FLOAT_APPROX 0.001f
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
G(TYPE_FUNCTION), \
|
G(TYPE_FUNCTION), \
|
||||||
G(TYPE_REF), \
|
G(TYPE_REF), \
|
||||||
G(TYPE_PROGRAM), \
|
G(TYPE_PROGRAM), \
|
||||||
G(TYPE_FLOAT), \
|
|
||||||
G(TYPE_ARRAY)
|
G(TYPE_ARRAY)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -109,13 +109,12 @@ TEST_CASE_METHOD(LexerTest, "Lexer_block")
|
||||||
test_end(lexer);
|
test_end(lexer);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(LexerTest, "Lexer_float")
|
TEST_CASE_METHOD(LexerTest, "Lexer_array")
|
||||||
{
|
{
|
||||||
grino::Lexer lexer {m_logger, "tests/lexer"};
|
grino::Lexer lexer {m_logger, "tests/lexer"};
|
||||||
|
|
||||||
lexer.scan(" 3.12 -0.7 1.0");
|
lexer.scan(" [] ");
|
||||||
test_next(lexer, "FLOAT[3.12]");
|
test_next(lexer, "OSQUARE");
|
||||||
test_next(lexer, "FLOAT[-0.7]");
|
test_next(lexer, "CSQUARE");
|
||||||
test_next(lexer, "FLOAT[1.0]");
|
|
||||||
test_end(lexer);
|
test_end(lexer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,9 +93,3 @@ TEST_CASE_METHOD(ParserTest, "Parser_array")
|
||||||
test_parse("MODULE(BLOCK(ARRAY(INT[1],BOOL[true],IDENT[salut])))",
|
test_parse("MODULE(BLOCK(ARRAY(INT[1],BOOL[true],IDENT[salut])))",
|
||||||
"(: [1 true salut] )");
|
"(: [1 true salut] )");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(ParserTest, "Parser_float")
|
|
||||||
{
|
|
||||||
test_parse("MODULE(BLOCK(ARRAY(INT[1],FLOAT[28.5],IDENT[salut])))",
|
|
||||||
"(: [1 28.5 salut] )");
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue