// lib/Perlito/Javascript/Runtime.js
//
// Runtime for "Perlito" Perlito-in-Javascript
//
// AUTHORS
//
// Flavio Soibelmann Glock fglock@gmail.com
// The Pugs Team perl6-compiler@perl.org
//
// SEE ALSO
//
// The Perl 6 homepage at http://dev.perl.org/perl6
// The Pugs homepage at http://pugscode.org/
//
// COPYRIGHT
//
// Copyright 2009, 2010, 2011 by Flavio Soibelmann Glock and others.
//
// This program is free software; you can redistribute it and/or modify it
// under the same terms as Perl itself.
//
// See http://www.perl.com/perl/misc/Artistic.html
List_ARGS = [];
if (typeof arguments == 'object' ) {
List_ARGS = arguments;
}
// class IO
if (typeof IO != 'object') {
IO = function() {};
IO = new IO;
}
IO.f_slurp = function (filename) {
if (typeof readFile == 'function' ) {
return readFile(filename);
}
if (typeof read == 'function' ) {
// v8
return read(filename);
}
f_die("IO.slurp() not implemented");
}
// class Main
if (typeof Main != 'object') {
Main = function() {};
Main = new Main;
}
(function () {
Main.f_lisp_escape_string = function (s) {
var o = s;
o = o.replace( /\\/g, "\\\\");
o = o.replace( /"/g, "\\\"");
return o;
}
Main.f_javascript_escape_string = function (s) {
var o = s;
o = o.replace( /\\/g, "\\\\");
o = o.replace( /"/g, "\\\"");
o = o.replace( /\n/g, "\\n");
return o;
}
Main.f_perl_escape_string = function (s) {
var o = s;
o = o.replace( /\\/g, "\\\\");
o = o.replace( /'/g, "\\'");
return o;
}
Main.f_to_javascript_namespace = function (s) {
var o = s;
o = o.replace( /::/g, "$");
return o;
}
Main.f_to_lisp_namespace = function (s) {
var o = s;
o = o.replace( /[$@%]/, "");
o = o.replace( /::/g, "-");
return "mp-" + o;
}
Main.f_to_go_namespace = function (s) {
var o = s;
o = o.replace( /[$@%]/, "");
o = o.replace( /::/g, "__");
return o;
}
Main._dump = function (o) {
var out = [];
for(var i in o) {
if ( i.match( /^v_/ ) ) {
out.push( i.substr(2) + " => " + f_perl(o[i]) )
}
}
return out.join(", ");
}
})();
if (typeof Perlito$Match != 'object') {
Perlito$Match = function() {};
Perlito$Match = new Perlito$Match;
Perlito$Match.f_isa = function (s) { return s == 'Perlito::Match' };
Perlito$Match.f_perl = function () { return 'Perlito::Match.new(' + Main._dump(this) + ')' };
}
v_MATCH = {};
v_MATCH.__proto__ = Perlito$Match;
Perlito$Match.f_hash = function () { return this }
if (typeof f_print != 'function') {
var buf = "";
f_print = function () {
var i;
for (i = 0; i < f_print.arguments.length; i++) {
var s = f_string( f_print.arguments[i] )
if ( s.substr(s.length - 2, 2 ) == "\n" ) {
print( buf + s.substr(0, s.length - 2) );
buf = "";
}
else if ( s.substr(s.length - 1, 1 ) == "\n" ) {
print( buf + s.substr(0, s.length - 1) );
buf = "";
}
else {
buf = buf + s;
}
}
return true;
}
}
if (typeof f_say != 'function') {
f_say = function () {
var i;
for (i = 0; i < f_say.arguments.length; i++) {
f_print( f_say.arguments[i] );
}
return f_print("\n");
}
}
if (typeof f_die != 'function') {
f_die = function (s) {
print("Died: " + s + "\n")
}
}
if (typeof f_warn != 'function') {
f_warn = function (s) {
print("Warning: " + s + "\n")
}
}
f_chr = function (o) {
return String.fromCharCode(o)
}
f_elems = function (o) {
if ( o == null ) { return 1 };
if ( typeof o.f_elems == 'function' ) { return o.f_elems() }
if ( typeof o == 'object' && (o instanceof Array) ) {
return o.length;
}
switch (typeof o){
case "string": return 1;
case "function": return 1;
case "number": return 1;
case "boolean": return 1;
}
var l = 0;
for(var i in o) {
l++
}
return l;
}
f_values = function (o) {
if ( o == null ) { return [] };
if ( typeof o.f_values == 'function' ) { return o.f_values() }
if ( typeof o == 'object' && (o instanceof Array) ) {
return o;
}
switch (typeof o){
case "string": return [o];
case "function": return [o];
case "number": return [o];
case "boolean": return [o];
}
var out = [];
for(var i in o) {
out.push( o[i] )
}
return out;
}
f_keys = function (o) {
if ( o == null ) { return [] };
if ( typeof o.f_keys == 'function' ) { return o.f_keys() }
var out = [];
if ( typeof o == 'object' && (o instanceof Array) ) {
var count = 0;
for(var i in o) {
out.push(count)
count++;
}
return out;
}
for(var i in o) {
out.push(i)
}
return out;
}
f_pairs = function (o) {
if ( o == null ) { return [] };
if ( typeof o.f_pairs == 'function' ) { return o.f_pairs() }
if ( typeof o == 'object' && (o instanceof Array) ) {
var count = 0;
for(var i in o) {
var tmp = {v_key: count,v_value: i};
tmp.__proto__ = Pair;
out.push(tmp)
count++;
}
return o;
}
var out = [];
for(var i in o) {
var tmp = {v_key: i,v_value: o[i]};
tmp.__proto__ = Pair;
out.push(tmp)
}
return out;
}
var _id = 0;
f_id = function (o) {
if ( o == null ) { return '_id_' + 'Mu' };
if ( typeof o.f_id == 'function' ) {
return o.f_id()
}
if ( o._id ) {
return o._id
}
switch (typeof o){
case "string": return '_id_str_' + o;
case "number": return '_id_num_' + o;
case "boolean": return '_id_bool_' + o;
}
o._id = ++_id;
return o._id;
}
f_perl = function (o) {
if ( o == null ) { return 'Mu' };
if ( typeof o.f_perl == 'function' ) { return o.f_perl() }
if ( typeof o == 'object' && (o instanceof Array) ) {
var out = [];
for(var i = 0; i < o.length; i++) { out.push( f_perl(o[i]) ) }
return "[" + out.join(", ") + "]";
}
switch (typeof o){
case "string": return '"' + Main.f_lisp_escape_string(o) + '"';
case "function": return "function";
case "number": return o;
case "boolean": return o;
}
var out = [];
for(var i in o) {
out.push( i + " => " + f_perl(o[i]) )
}
return '{' + out.join(", ") + '}';
}
f_isa = function (o, s) {
if ( o == null ) {
if ( s == 'Mu' ) { return true } else { return false }
}
if ( typeof o.f_isa == 'function' ) { return o.f_isa(s) }
switch (typeof o){
case "string": return(s == 'Str');
case "number": return(s == 'Num');
}
if ( s == 'Array' && typeof o == 'object' && (o instanceof Array) ) { return(1) }
return false;
}
f_scalar = function (o) {
if ( o == null ) { return o }
if ( typeof o.f_scalar == 'function' ) { return o.f_scalar() }
return o;
}
f_string = function (o) {
if ( o == null ) { return "" }
if ( typeof o == 'object' && (o instanceof Array) ) {
var out = [];
for(var i = 0; i < o.length; i++) { out.push( f_string(o[i]) ) }
return out.join(" ");
}
if ( typeof o.f_string == 'function' ) { return o.f_string() }
if ( typeof o != 'string' ) { return "" + o }
return o;
}
f_add = function (o1, o2) {
if ( typeof o1 == 'string' ) {
if ( typeof o2 == 'string' ) {
return parseFloat(o1) + parseFloat(o2)
}
return parseFloat(o1) + o2
}
if ( typeof o2 == 'string' ) {
return o1 + parseFloat(o2)
}
return o1 + o2;
}
f_bool = function (o) {
if ( o == null ) { return o }
if ( typeof o == 'boolean' ) { return o }
if ( typeof o == 'number' ) { return o }
if ( typeof o == 'string' ) { return o != '' && o != '0' }
if ( typeof o.f_bool == 'function' ) { return o.v_bool }
if ( typeof o.length == 'number' ) { return o.length }
return o;
}
f_and = function (a, fb) {
if (f_bool(a)) { return fb() }
return a
}
f_or = function (a, fb) {
if (f_bool(a)) { return a }
return fb()
}
f_defined_or = function (a, fb) {
if ( a == null ) { return fb() }
return a
}
f_pop = function (o) {
if (o.length == null ) { return null }
return o.pop();
}
f_shift = function (o) {
if (o.length == null ) { return null }
return o.shift();
}
f_push = function (o, v) {
return o.push(v);
}
f_unshift = function (o, v) {
return o.unshift(v);
}
f_index = function (o, s) {
return o.indexOf(s);
}
f_chars = function (o) {
if ( typeof o.f_string == 'function' ) { return o.f_string().length }
return o.length;
}
// regex primitives
if (typeof Perlito$Grammar != 'object') {
Perlito$Grammar = function() {};
Perlito$Grammar = new Perlito$Grammar;
}
Perlito$Grammar.f_word = function (v_str, v_pos) {
var tmp = {
v_str: v_str,
v_from: v_pos,
v_to: v_pos + 1,
v_bool: v_str.substr(v_pos, 1).match(/\w/) != null
};
tmp.__proto__ = Perlito$Match;
return tmp;
}
Perlito$Grammar.f_digit = function (v_str, v_pos) {
var tmp = {
v_str: v_str,
v_from: v_pos,
v_to: v_pos + 1,
v_bool: v_str.substr(v_pos, 1).match(/\d/) != null
};
tmp.__proto__ = Perlito$Match;
return tmp;
}
Perlito$Grammar.f_space = function (v_str, v_pos) {
var tmp = {
v_str: v_str,
v_from: v_pos,
v_to: v_pos + 1,
v_bool: v_str.substr(v_pos, 1).match(/\s/) != null
};
tmp.__proto__ = Perlito$Match;
return tmp;
}
Perlito$Grammar.f_is_newline = function (v_str, v_pos) {
var m_ = v_str.substr(v_pos).match(/^(\r\n?|\n\r?)/);
var tmp = {
v_str: v_str,
v_from: v_pos,
v_to: m_ != null ? v_pos + m_[0].length : v_pos,
v_bool: m_ != null
};
tmp.__proto__ = Perlito$Match;
return tmp;
}
Perlito$Grammar.f_not_newline = function (v_str, v_pos) {
var tmp = {
v_str: v_str,
v_from: v_pos,
v_to: v_pos + 1,
v_bool: v_str.substr(v_pos, 1).match(/[^\r\n]/) != null
};
tmp.__proto__ = Perlito$Match;
return tmp;
}