changeset 7:8af72f11714e

Initial version of FFI
author Mike Pavone <pavone@retrodev.com>
date Wed, 21 Mar 2012 20:12:12 -0700
parents 554602d4cbc6
children 04ae32e91598
files parser.js
diffstat 1 files changed, 50 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/parser.js	Wed Mar 21 08:42:12 2012 -0700
+++ b/parser.js	Wed Mar 21 20:12:12 2012 -0700
@@ -28,6 +28,12 @@
 }
 osymbols.prototype.find = function(name) {
 	if (name in this.names) {
+		if (this.names[name] instanceof funcall && this.names[name].name == 'foreign:') {
+			return {
+				type: 'foreign',
+				def: this.names[name]
+			};
+		}
 		return {
 			type: 'self',
 			def: this.names[name],
@@ -66,6 +72,12 @@
 }
 lsymbols.prototype.find = function(name) {
 	if (name in this.names) {
+		if (this.names[name] instanceof funcall && this.names[name].name == 'foreign:') {
+			return {
+				type: 'foreign',
+				def: this.names[name]
+			};
+		}
 		return {
 			type: 'local',
 			def: this.names[name]
@@ -119,7 +131,15 @@
 }
 symbol.prototype.toJS = function(symbols) {
 	var name = this.cleanName();
-	return name == 'self' ? symbols.selfVar() : 's' + name.replace("_", "UN_").replace(":", "CN_").replace("!", "EX_").replace('?', 'QS_').replace('@', 'AT_');
+	if (name == 'self') {
+		return symbols.selfVar();
+	}
+	name = name.replace("_", "UN_").replace(":", "CN_").replace("!", "EX_").replace('?', 'QS_').replace('@', 'AT_');
+	var reserved = {'true': true, 'false': true, 'this': true, 'if': true, 'else': true, 'NaN': true};
+	if (name in reserved) {
+		name = 's' + name;
+	}
+	return name;
 }
 symbol.prototype.cleanName = function() {
 	return this.name[0] == ':' ? this.name.substr(1) : this.name;
@@ -146,6 +166,7 @@
 	this.val = val;
 }
 strlit.prototype.toJS = function(symbols) {
+	console.log('string:', this.val);
 	return '"' + this.val.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n').replace('\r', '\\r') + '"';
 }
 
@@ -188,10 +209,17 @@
 		for (var i = 0; i < funinfo.depth; ++i) {
 			ret += '.parent';
 		}
+		for (var i in args) {
+			args[i] = args[i].toJS(symbols);
+		}
 		ret += (new symbol(name)).toJS(symbols) + '(' + args.join(', ') + ')';
 		return ret;
 	case 'local':
 	case 'upvar':
+	case 'foreign':
+		for (var i in args) {
+			args[i] = args[i].toJS(symbols);
+		}
 		return (new symbol(name)).toJS(symbols) + '(' + args.join(', ') + ')';
 	}
 }
@@ -201,12 +229,16 @@
 	this.messages = messages;
 }
 object.prototype.toJS = function(symbols) {
-	var messages = this.messages.slice(0, this.messages.length);
+	var messages = this.messages;
 	symbols = new osymbols(symbols);
+	var compiled = []
 	for (var i in messages) {
-		messages[i] = indent(messages[i].toJSObject(symbols));
+		var js = messages[i].toJSObject(symbols);
+		if (js) {
+			compiled.push(indent(js));
+		}
 	}
-	return '{\n\tparent: ' + symbols.parentObject() + ',\n\t' + messages.join(',\n\t') + '\n}';
+	return '{\n\tparent: ' + symbols.parentObject() + ',\n\t' + compiled.join(',\n\t') + '\n}';
 }
 
 object.prototype.toJSModule = function() {
@@ -223,15 +255,20 @@
 	if (args.length && args[0].cleanName() == 'self') {
 		args.splice(0, 1);
 	}
-	var exprs = this.expressions.slice(0, this.expressions.length);
+	var exprs = this.expressions;
 	symbols = new lsymbols(symbols);
 	for (var i in args) {
 		symbols.defineVar(args[i].cleanName(), null);
 		args[i] = args[i].toJS(symbols);
 	}
+	var compiled = []
 	for (var i in exprs) {
-		exprs[i] = indent(exprs[i].toJS(symbols));
+		var js = exprs[i].toJS(symbols);
+		if (js) {
+			compiled.push(indent(js));
+		}
 	}
+	exprs = compiled;
 	if (exprs.length) {
 		exprs[exprs.length-1] = 'return ' + exprs[exprs.length-1] + ';';
 	}
@@ -264,10 +301,16 @@
 			break;
 		}
 	}
+	if (this.expression instanceof funcall && this.expression.name == 'foreign:') {
+		return null;
+	}
 	return prefix + this.symbol.toJS(symbols) + ' = ' + this.expression.toJS(symbols);
 };
 assignment.prototype.toJSObject = function(symbols) {
 	symbols.defineMsg(this.symbol.name, this.expression);
+	if (this.expression instanceof funcall && this.expression.name == 'foreign:') {
+		return null;
+	}
 	return this.symbol.toJS(symbols) + ': ' + this.expression.toJS(symbols);
 };
 
@@ -325,7 +368,7 @@
 			var parsed = parser.parse(text);
 			var js = parsed.toJSModule();
 			mainModule = eval(js)();
-			q('pre').innerHTML = mainModule.smain();
+			q('pre').innerHTML = mainModule.main();
 		/*} catch(e) {
 			q('pre').innerHTML = e.message + '\nLine: ' + e.line + '\nCol: ' + e.column;
 		}*/