diff --git a/apps/furnace-fjsc/repl.fhtml b/apps/furnace-fjsc/repl.fhtml
index e50870d923..057ba5154a 100644
--- a/apps/furnace-fjsc/repl.fhtml
+++ b/apps/furnace-fjsc/repl.fhtml
@@ -1,5 +1,5 @@
diff --git a/apps/furnace-fjsc/resources/bootstrap.js b/apps/furnace-fjsc/resources/bootstrap.js
index b791a91129..942d399789 100644
--- a/apps/furnace-fjsc/resources/bootstrap.js
+++ b/apps/furnace-fjsc/resources/bootstrap.js
@@ -10,6 +10,10 @@ function Factor() {
"*": function() { self.fjsc_times(); },
"/": function() { self.fjsc_divide(); },
".": function() { self.fjsc_dot(); },
+ "call": function() { self.fjsc_call(); },
+ "map": function() { self.fjsc_map(); },
+ "reduce": function() { self.fjsc_reduce(); },
+ "clear": function() { self.fjsc_clear(); },
alert: function() { self.fjsc_alert(); }
};
}
@@ -92,9 +96,42 @@ Factor.prototype.fjsc_dot = function() {
alert(this.data_stack.pop());
}
+Factor.prototype.fjsc_call = function() {
+ (this.data_stack.pop())();
+}
+
+Factor.prototype.fjsc_map = function() {
+ var quot = this.data_stack.pop();
+ var seq = this.data_stack.pop();
+ var result = [ ];
+ for(var i=0;i ;
LAZY: 'identifier-middle' ( -- parser )
[
[ blank? not ] keep
+ [ CHAR: [ = not ] keep
+ [ CHAR: ] = not ] keep
+ [ CHAR: { = not ] keep
+ [ CHAR: } = not ] keep
[ CHAR: : = not ] keep
[ CHAR: " = not ] keep
[ CHAR: ; = not ] keep
digit? not
- and and and and
+ and and and and and and and and
] satisfy <+> ;
USE: prettyprint
@@ -56,29 +66,55 @@ LAZY: 'define' ( -- parser )
'expression' <&>
";" token sp <& [ first2 ] <@ ;
+LAZY: 'quotation' ( -- parser )
+ "[" token sp
+ 'expression' &>
+ "]" token sp <& [ ] <@ ;
+
+LAZY: 'array' ( -- parser )
+ "{" token sp
+ 'expression' &>
+ "}" token sp <& [ ] <@ ;
+
LAZY: 'atom' ( -- parser )
'identifier' 'number' <|> 'string' <|> ;
LAZY: 'expression' ( -- parser )
- 'define' sp 'atom' sp <|> <*> [ ] <@ ;
+ 'define' sp
+ 'atom' sp <|>
+ 'quotation' sp <|>
+ 'array' sp <|>
+ <*> [ ] <@ ;
LAZY: 'statement' ( -- parser )
'define' 'expression' <|> ;
GENERIC: (compile) ( ast -- )
+GENERIC: (literal) ( ast -- )
+
+M: ast-number (literal)
+ ast-number-value number>string , ;
M: ast-number (compile)
"factor.data_stack.push(" ,
- ast-number-value number>string ,
- ")" , ;
+ (literal)
+ ");" , ;
+
+M: ast-string (literal)
+ "'" ,
+ ast-string-value ,
+ "'" , ;
M: ast-string (compile)
- "factor.data_stack.push('" ,
- ast-string-value ,
- "')" , ;
+ "factor.data_stack.push(" ,
+ (literal)
+ ");" , ;
+
+M: ast-identifier (literal)
+ "factor.words[\"" , ast-identifier-value , "\"]" , ;
M: ast-identifier (compile)
- "factor.words[\"" , ast-identifier-value , "\"]()" , ;
+ (literal) "();" , ;
M: ast-define (compile)
"factor.words[\"" ,
@@ -87,13 +123,41 @@ M: ast-define (compile)
ast-define-expression (compile)
"}" , ;
-M: ast-expression (compile)
+M: ast-quotation (literal)
+ "function() { " ,
+ ast-quotation-expression (compile)
+ "}" , ;
+
+M: ast-quotation (compile)
+ "factor.data_stack.push(" ,
+ (literal)
+ ")" , ;
+
+M: ast-array (literal)
+ "[" ,
+ ast-array-elements ast-expression-values [ (literal) ] [ "," , ] interleave
+ "]" , ;
+
+M: ast-array (compile)
+ "factor.data_stack.push(" ,
+ (literal)
+ ")" , ;
+
+M: ast-expression (literal)
ast-expression-values [
- (compile) "; " ,
+ (literal)
] each ;
+M: ast-expression (compile)
+ ast-expression-values [ (compile) ] [ ";" , ] interleave ;
+
: fjsc-compile ( ast -- string )
[
[ (compile) ] { } make [ write ] each
] string-out ;
+: fjsc-literal ( ast -- string )
+ [
+ [ (literal) ] { } make [ write ] each
+ ] string-out ;
+
\ No newline at end of file
diff --git a/libs/fjsc/tests.factor b/libs/fjsc/tests.factor
index 01d25f6af2..95d7df9334 100644
--- a/libs/fjsc/tests.factor
+++ b/libs/fjsc/tests.factor
@@ -8,23 +8,31 @@ IN: temporary
"55 2abc1 100" 'expression' parse car parse-result-parsed
] unit-test
-{ "factor.words[\"alert\"]()" } [
+{ T{ ast-quotation f T{ ast-expression f { T{ ast-number f 55 } T{ ast-identifier f "2abc1" } T{ ast-number f 100 } } } } } [
+ "[ 55 2abc1 100 ]" 'quotation' parse car parse-result-parsed
+] unit-test
+
+{ T{ ast-array f T{ ast-expression f { T{ ast-number f 55 } T{ ast-identifier f "2abc1" } T{ ast-number f 100 } } } } } [
+ "{ 55 2abc1 100 }" 'array' parse car parse-result-parsed
+] unit-test
+
+{ "factor.words[\"alert\"]();" } [
"alert" 'identifier' parse car parse-result-parsed fjsc-compile
] unit-test
-{ "factor.data_stack.push(123); factor.words[\"alert\"](); " } [
+{ "factor.data_stack.push(123);factor.words[\"alert\"]();" } [
"123 alert" 'expression' parse car parse-result-parsed fjsc-compile
] unit-test
-{ "factor.data_stack.push(123); factor.data_stack.push('hello'); factor.words[\"alert\"](); " } [
+{ "factor.data_stack.push(123);factor.data_stack.push('hello');factor.words[\"alert\"]();" } [
"123 \"hello\" alert" 'expression' parse car parse-result-parsed fjsc-compile
] unit-test
-{ "factor.words[\"foo\"]=function() { factor.data_stack.push(123); factor.data_stack.push('hello'); }" } [
+{ "factor.words[\"foo\"]=function() { factor.data_stack.push(123);factor.data_stack.push('hello');}" } [
": foo 123 \"hello\" ;" 'define' parse car parse-result-parsed fjsc-compile
] unit-test
-{ "factor.words[\"foo\"]=function() { factor.data_stack.push(123); factor.data_stack.push('hello'); }; " } [
+{ "factor.words[\"foo\"]=function() { factor.data_stack.push(123);factor.data_stack.push('hello');}" } [
": foo 123 \"hello\" ;" 'expression' parse car parse-result-parsed fjsc-compile
] unit-test