Mercurial > projects > dmdscript-tango
view dmdscript_tango/script.d @ 4:6d905019f7bf
some changes
author | saaadel |
---|---|
date | Thu, 28 Jan 2010 21:23:27 +0200 |
parents | 8363a4bf6a8f |
children |
line wrap: on
line source
/* Digital Mars DMDScript source code. * Copyright (c) 2000-2002 by Chromium Communications * D version Copyright (c) 2004-2006 by Digital Mars * All Rights Reserved * written by Walter Bright * www.digitalmars.com * Use at your own risk. There is no warranty, express or implied. * License for redistribution is by the GNU General Public License in gpl.txt. * * A binary, non-exclusive license for commercial use can be * purchased from www.digitalmars.com/dscript/buy.html. * * DMDScript is implemented in the D Programming Language, * www.digitalmars.com/d/ * * For a C++ implementation of DMDScript, including COM support, * see www.digitalmars.com/dscript/cppscript.html. */ module dmdscript_tango.script; import std.ctype; import std.string; import std.c.stdlib; import std.c.stdarg; /* =================== Configuration ======================= */ const uint MAJOR_VERSION = 5; // ScriptEngineMajorVersion const uint MINOR_VERSION = 5; // ScriptEngineMinorVersion const uint BUILD_VERSION = 1; // ScriptEngineBuildVersion const uint JSCRIPT_CATCH_BUG = 1; // emulate Jscript's bug in scoping of // catch objects in violation of ECMA const uint JSCRIPT_ESCAPEV_BUG = 0; // emulate Jscript's bug where \v is // not recognized as vertical tab //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= alias char tchar; alias ulong number_t; alias double real_t; alias uint Loc; // file location (line number) struct ErrInfo { tchar[] message; // error message (null if no error) tchar[] srcline; // string of source line (null if not known) uint linnum; // source line number (1 based, 0 if not available) int charpos; // character position (1 based, 0 if not available) int code; // error code (0 if not known) } class ScriptException : Exception { ErrInfo ei; this(tchar[] msg) { ei.message = msg; super(msg); } this(ErrInfo* pei) { ei = *pei; super(ei.message); } } int logflag; // used for debugging // Aliases for script primitive types alias uint d_boolean; alias double d_number; alias int d_int32; alias uint d_uint32; alias ushort d_uint16; alias tchar[] d_string; import dmdscript_tango.value; import dmdscript_tango.dobject; import dmdscript_tango.program; import dmdscript_tango.text; import dmdscript_tango.functiondefinition; struct CallContext { Dobject[] scopex; // current scope chain Dobject variable; // object for variable instantiation Dobject global; // global object uint scoperoot; // number of entries in scope[] starting from 0 // to copy onto new scopes uint globalroot; // number of entries in scope[] starting from 0 // that are in the "global" context. Always <= scoperoot void* lastnamedfunc; // points to the last named function added as an event Program prog; Dobject callerothis; // caller's othis Dobject caller; // caller function object FunctionDefinition callerf; char[16] value; // place to store exception; must be same size as Value uint linnum; // source line number of exception (1 based, 0 if not available) int finallyret; // !=0 if IRfinallyret was executed int Interrupt; // !=0 if cancelled due to interrupt } struct Global { tchar[] copyright = "Copyright (c) 1999-2009 by Digital Mars"; tchar[] written = "written by Walter Bright"; } Global global; tchar[] banner() { return std.string.format( "Digital Mars DMDScript 1.15\n", "http://www.digitalmars.com\n", "Compiled by Digital Mars DMD D compiler\n", global.copyright, "\n", global.written); } int isStrWhiteSpaceChar(dchar c) { switch (c) { case ' ': case '\t': case 0xA0: // <NBSP> case '\f': case '\v': case '\r': case '\n': case 0x2028: // <LS> case 0x2029: // <PS> case 0x2001: // <USP> case 0x2000: // should we do this one? return 1; default: break; } return 0; } /************************ * Convert d_string to an index, if it is one. * Returns: * true it's an index, and *index is set * false it's not an index */ int StringToIndex(d_string name, out d_uint32 index) { if (name.length) { d_uint32 i = 0; for (uint j = 0; j < name.length; j++) { tchar c = name[j]; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if ((i == 0 && j) || // if leading zeros i >= 0xFFFFFFFF / 10) // or overflow goto Lnotindex; i = i * 10 + c - '0'; break; default: goto Lnotindex; } } index = i; return true; } Lnotindex: return false; } /******************************** * Parse string numeric literal into a number. * Input: * parsefloat 0: convert per ECMA 9.3.1 * 1: convert per ECMA 15.1.2.3 (global.parseFloat()) */ d_number StringNumericLiteral(d_string string, out size_t endidx, int parsefloat) { // Convert StringNumericLiteral using ECMA 9.3.1 d_number number; int sign = 0; size_t i; size_t len; size_t eoff; // Skip leading whitespace eoff = string.length; foreach (size_t j, dchar c; string) { if (!isStrWhiteSpaceChar(c)) { eoff = j; break; } } string = string[eoff .. length]; len = string.length; // Check for [+|-] i = 0; if (len) { switch (string[0]) { case '+': sign = 0; i++; break; case '-': sign = 1; i++; break; default: sign = 0; break; } } size_t inflen = TEXT_Infinity.length; if (len - i >= inflen && string[i .. i + inflen] == TEXT_Infinity) { number = sign ? -d_number.infinity : d_number.infinity; endidx = eoff + i + inflen; } else if (len - i >= 2 && string[i] == '0' && (string[i + 1] == 'x' || string[i + 1] == 'X')) { // Check for 0[x|X]HexDigit... number = 0; if (parsefloat) { // Do not recognize the 0x, treat it as if it's just a '0' i += 1; } else { i += 2; for (; i < len; i++) { tchar c; c = string[i]; // don't need to decode UTF here if ('0' <= c && c <= '9') number = number * 16 + (c - '0'); else if ('a' <= c && c <= 'f') number = number * 16 + (c - 'a' + 10); else if ('A' <= c && c <= 'F') number = number * 16 + (c - 'A' + 10); else break; } } if (sign) number = -number; endidx = eoff + i; } else { char* endptr; char* s = std.string.toStringz(string[i .. len]); endptr = s; number = std.c.stdlib.strtod(s, &endptr); endidx = (endptr - s) + i; //printf("s = '%s', endidx = %d, eoff = %d, number = %g\n", s, endidx, eoff, number); // Correctly produce a -0 for the // string "-1e-2000" if (sign) number = -number; if (endidx == i && (parsefloat || i != 0)) number = d_number.nan; endidx += eoff; } return number; } int localeCompare(CallContext *cc, d_string s1, d_string s2) { // no locale support here return std.string.cmp(s1, s2); }