Permalink
Browse files

day 1 wip

  • Loading branch information...
ujihisa committed Dec 31, 2012
0 parents commit 6902cd4e9382e2da58fb9d43f8069256e8fe1ded
Showing with 133 additions and 0 deletions.
  1. +78 −0 README.md
  2. +39 −0 runtime.clj
  3. +16 −0 sample.js
@@ -0,0 +1,78 @@
# JavaScript in a week
## Day 1 defining a subset of JavaScript
The implementation should execute the following JavaScript code.
```js
var acc = 'dummy';
var f = function() {
var acc = [];
return function(x) {
return x ? acc.push(x)&&f(x - 1) : acc;
};
console.log("this won't show up!");
}();
String.prototype.ujihisa = function() {
var x = 10;
return this + f(x);
}
console.log("hello".ujihisa());
console.log(acc == 'dummy');
console.log({'a': 2}.a == 2);
```
hello10,9,8,7,6,5,4,3,2,1
true
That code covers the following important aspects.
* statements and expressions
* literals (String, Number, Function, Array and Object)
* function call, method call, operators, and index/key access of Object
* implicit convertion (String + Number)
* lexical scope (see `acc` var)
* method addition by prototype
* `return` exits from the current function
The implementation consists of
* parser (JS code to internal representation in S-expression)
* runtime
I'll work on runtime first in Clojure, then work on parser in Haskell with parsec.
### parsing
I don't implement the parser for now but I simply parse the sample code by hand. the first 2 statements will be like the below.
before:
```js
var acc = 'dummy';
var f = function() {
var acc = [];
return function(x) {
return x ? acc.push(x)&&f(x - 1) : acc;
};
}();
```
after:
```clojure
'[(var 'acc "dummy")
(var 'f
(call
(function []
[[(var 'acc (array))
(return
(function ['x]
[[(return (if 'x
(and (mcall 'push 'acc ['x])
(call 'f [(minus 'x 1)]))
'acc))]]))]])
[]))]
```
@@ -0,0 +1,39 @@
(def sample-parsed
'[(var acc "dummy")
(var f
(fcall
(function []
[[(var acc (array))
(return
(function ['x]
[[(return (if 'x
(and (mcall 'push 'acc ['x])
(fcall 'f [(minus 'x 1)]))
'acc))]]))]])
[]))])
(defn evaluate [expr env]
"assumption: env won't change"
(if (= 'quote (first expr))
(get env (second expr))
expr))
(defn run [exprs]
(loop [[expr & exprs] exprs env {'console.log 'console.log}]
(when expr
(if-let [[car & cdr] expr]
(do
#_(prn car cdr env)
(condp = car
'var (let [vname (first cdr)
vvalue (evaluate (second cdr) env)]
(recur exprs (assoc env vname vvalue)))
'fcall (let [func (evaluate (first cdr) env)
args (map #(evaluate % env) (second cdr))]
(condp = func
'console.log (println (first args))
(prn 'must-not-happen 'missing-function)))
(prn 'must-not-happen expr)))
expr))))
(run '[(var x "hello") (fcall 'console.log ['x])])
@@ -0,0 +1,16 @@
var acc = 'dummy';
var f = function() {
var acc = [];
return function(x) {
return x ? acc.push(x)&&f(x - 1) : acc;
};
}();
String.prototype.ujihisa = function() {
var x = 10;
return this + f(x);
}
console.log("hello".ujihisa());
console.log(acc == 'dummy');
console.log({'a': 2}.a == 2);

0 comments on commit 6902cd4

Please sign in to comment.