Skip to content

Commit 6858e9e

Browse files
committed
added new syntax for super (^) and Worlds/JS implementation
1 parent 7e06b01 commit 6858e9e

File tree

9 files changed

+1156
-2
lines changed

9 files changed

+1156
-2
lines changed

OMeta_WJS.wjs

Lines changed: 624 additions & 0 deletions
Large diffs are not rendered by default.

OMeta_WJS_Mods.js

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
OMeta._or = function() {
2+
for (var idx = 0; idx < arguments.length; idx++) {
3+
var ok = true
4+
in thisWorld.sprout() {
5+
try { return arguments[idx]() }
6+
catch (f) {
7+
ok = false
8+
if (f != fail)
9+
throw f
10+
}
11+
finally { if (ok) thisWorld.commit() }
12+
}
13+
}
14+
throw fail
15+
}
16+
17+
OMeta._many = function(x) {
18+
var ans = arguments[1] != undefined ? [arguments[1]] : []
19+
while (true) {
20+
in thisWorld.sprout() {
21+
try {
22+
ans.push(x())
23+
//print("committing " + ans.toString())
24+
thisWorld.commit()
25+
}
26+
catch (f) {
27+
if (f != fail)
28+
throw f
29+
break
30+
}
31+
}
32+
}
33+
return ans
34+
}
35+
36+
OMeta._not = function(x) {
37+
in thisWorld.sprout() {
38+
try { x() }
39+
catch (f) {
40+
if (f != fail)
41+
throw f
42+
return true
43+
}
44+
}
45+
throw fail
46+
}
47+
48+
/*
49+
OMeta._lookahead = function(x) {
50+
in thisWorld.sprout() {
51+
var r = x()
52+
//print("la = " + r.toString())
53+
return x
54+
}
55+
}
56+
*/
57+
58+
/*
59+
OMeta._apply = function(rule) {
60+
var memoRec = this.input.memo[rule]
61+
if (memoRec == undefined) {
62+
var origInput = this.input,
63+
failer = new Failer()
64+
this.input.memo[rule] = failer
65+
this.input.memo[rule] = memoRec = {ans: this[rule].apply(this), nextInput: this.input}
66+
if (failer.used) {
67+
var sentinel = this.input
68+
while (true) {
69+
try {
70+
this.input = origInput
71+
var ans = this[rule].apply(this)
72+
if (this.input == sentinel)
73+
throw fail
74+
memoRec.ans = ans
75+
memoRec.nextInput = this.input
76+
}
77+
catch (f) {
78+
if (f != fail)
79+
throw f
80+
break
81+
}
82+
}
83+
}
84+
}
85+
else if (memoRec instanceof Failer) {
86+
memoRec.used = true
87+
throw fail
88+
}
89+
this.input = memoRec.nextInput
90+
return memoRec.ans
91+
}
92+
*/
93+
94+
95+
print("defining example 1")
96+
eval(BSOMetaJSTranslator.match(BSOMetaJSParser.matchAll("ometa M { ones = (1 -> 2)* }", "srcElem"), "trans"))
97+
print("running example 1")
98+
print(M.matchAll([1, 1, 1, 1], "ones"))
99+
100+
print("defining example 2")
101+
eval(BSOMetaJSTranslator.match(BSOMetaJSParser.matchAll("ometa M { foo = &(:x) anything*:ys -> [x, ys] }", "srcElem"), "trans"))
102+
print("running example 2")
103+
print(M.matchAll([1, 2, 3, 4], "foo"))
104+
105+
print("defining example 3")
106+
eval(BSOMetaJSTranslator.match(BSOMetaJSParser.matchAll("ometa M { ones = {count=0} ({count++} 1 -> 2)* }", "srcElem"), "trans"))
107+
print("running example 3")
108+
print(M.matchAll([1, 1, 1, 1], "ones"))
109+
print("count = " + count)
110+

Worlds2.js

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
Array.prototype.each = function(f) {
2+
for (var idx = 0; idx < this.length; idx++)
3+
f(this[idx], idx)
4+
}
5+
6+
7+
8+
/*
9+
Copyright (c) 2008 Alessandro Warth <[email protected]>
10+
11+
TODO: make assignment into properties of argument work, e.g., arguments[5] = 1234
12+
TODO: make for-in work when variable is a property access, e.g., for (x.y in ys) ...
13+
*/
14+
15+
ometa WJSParser <: BSJSParser {
16+
isKeyword :x = ?(x == 'thisWorld')
17+
| super('isKeyword', x),
18+
primExprHd = "thisWorld" -> ['thisWorld']
19+
| super('primExprHd'),
20+
stmt = "in" expr:w block:b -> ['in', w, b]
21+
| super('stmt')
22+
}
23+
24+
makeFunction = function(fs, body) {
25+
return '(function() { var staticScope = thisScope;' +
26+
' var r = function() {' +
27+
' var oldScope = thisScope;' +
28+
' thisScope = staticScope.makeChild();' +
29+
/*
30+
' thisScope.set("arguments", arguments);' +
31+
' thisWorld.set(arguments, "length", arguments.length);' +
32+
' for (var i = 0; i < arguments.length; i++) thisWorld.set(arguments, i, arguments[i]);' +
33+
*/
34+
' try { ' + fs + body + '}' +
35+
' catch (e) { throw e }' +
36+
' finally { thisScope = oldScope }};' +
37+
' baseWorld.set(r, "prototype", {parent: Object.prototype});' +
38+
' return r })()' }
39+
40+
makeIn = function(w, body) {
41+
return '{ try { worldStack.push(thisWorld); thisWorld = ' + w + '; ' + body + '} ' +
42+
'catch (e) { throw e } ' +
43+
'finally { thisWorld = worldStack.pop() }' +
44+
'undefined }'
45+
}
46+
47+
makeForIn = function(v, e, s, decl) {
48+
var p = tempnam(), ps = tempnam()
49+
var r = 'for (var ' + p + ' in ' + ps + ' = thisWorld.props(' + e + ', {})) {' +
50+
'if (!' + ps + '.hasOwnProperty(' + p + ')) continue; ' +
51+
'thisScope.set("' + v + '", ' + p + '); ' + s +
52+
'}'
53+
if (decl)
54+
r = 'thisScope.decl("' + v + '", undefined); ' + r
55+
r = '{ var ' + ps + ' = undefined; ' + r + '}'
56+
return r
57+
}
58+
59+
ometa WJSTranslator <: BSJSTranslator {
60+
initialize = { self.level = 0 },
61+
fargs = [anything*:fs] -> { var ss = []
62+
fs.each(function(v, i) { ss.push('thisScope.decl("' + v +
63+
'", arguments[' + i + ']);') })
64+
ss.join('') },
65+
thisWorld -> 'thisWorld',
66+
var :n trans:v -> ('thisScope.decl("' + n + '", ' + v + ')'),
67+
get :n -> ('thisScope.get("' + n + '")'),
68+
getp trans:p ['get' 'arguments'] -> ('arguments[' + p + ']'),
69+
getp trans:p trans:x -> ('thisWorld.get(' + x + ', ' + p + ')'),
70+
set ['get' :n] trans:v -> ('thisScope.set("' + n + '", ' + v + ')'),
71+
set ['getp' trans:p ['get' 'arguments']] trans:v -> 'UNSUPPORTED OPERATION',
72+
set ['getp' trans:p trans:x] trans:v -> ('thisWorld.set(' + x + ', ' + p + ', ' + v + ')'),
73+
mset ['get' :n] :op trans:rhs -> ('thisScope.set("' + n + '", thisScope.get("' + n + '")' + op + rhs + ')'),
74+
mset ['getp' trans:p trans:x] :op trans:rhs -> ('(function(r, p) { return thisWorld.set(r, p, thisWorld.get(r, p) ' +
75+
op + ' ' + rhs + ') })(' + x + ', ' + p + ')'),
76+
preop :op ['get' :n] -> ('thisScope.set("' + n + '", thisScope.get("' + n + '")' + op[0] + '1)'),
77+
preop :op ['getp' trans:p trans:x] -> ('(function(r, p) { return thisWorld.set(r, p, thisWorld.get(r, p) ' +
78+
op[0] + ' 1) })(' + x + ', ' + p + ')'),
79+
postop :op ['get' :n] -> ('(function(n) { var ans = thisScope.get(n); ' +
80+
'thisScope.set(n, ans ' + op[0] + ' 1); ' +
81+
'return ans })("' + n + '")'),
82+
postop :op ['getp' trans:p trans:x] -> ('(function(r, p) { var ans = thisWorld.get(r, p); ' +
83+
'thisWorld.set(r, p, ans ' + op[0] + ' 1); ' +
84+
'return ans })(' + x + ', ' + p + ')'),
85+
binop 'instanceof' trans:x trans:y -> ('instanceOf(' + x + ', ' + y + ')'),
86+
binop :op trans:x trans:y -> ('(' + x + ' ' + op + ' ' + y + ')'),
87+
call trans:f trans*:as -> ('(' + f + ')(' + as.join(',') + ')'),
88+
send :m trans:r trans*:as -> ('send("' + m + '", ' + r + ', [' + as.join(',') + '])'),
89+
new :x trans*:as -> ('thisScope.get("' + x + '").worldsNew(' + as.join(',') + ')'),
90+
func fargs:fs {self.level++} trans:body
91+
{self.level--} -> makeFunction(fs, body),
92+
in trans:w trans:b -> makeIn(w, b),
93+
arr trans*:xs -> ('[' + xs.join(',') + '].toWJSArray()'),
94+
json trans*:xs -> ('({' + xs.join(',') + '}).toWJSObject()'),
95+
try curlyTrans:x :name curlyTrans:c curlyTrans:f -> { var e = tempnam()
96+
'try ' + x +
97+
'catch(' + e + ') {thisScope.decl("' + name + '", ' + e + '); ' + c + '}' +
98+
'finally' + f },
99+
forIn ['get' :v ] trans:e trans:s -> makeForIn(v, e, s, false),
100+
forIn ['var' :v :init] trans:e trans:s -> makeForIn(v, e, s, true)
101+
}
102+
103+
compileWJS = function(code) {
104+
var tree = WJSParser.matchAll(code, "topLevel", undefined, function(m, i) { throw fail.delegated({errorPos: i}) })
105+
//print("parsed: " + tree)
106+
var code = WJSTranslator.match(tree, 'trans')
107+
//print("compiled: " + code)
108+
return code
109+
}
110+
111+
thisScope.decl("eval", function(s) { return eval(compileWJS(s)) })
112+
113+
oldPrint = print
114+
print = function(x) { oldPrint(x == undefined || x == null ? x : send("toString", x)) }
115+
116+
translateCode = compileWJS
117+

0 commit comments

Comments
 (0)