📄 process.js
字号:
/* Handle the different types. */
if (this.return_type == tCSTRING)
{
stream.write ("\
cp = (char *) js_vm_alloc (vm, vm->exec_result.u.vstring->len + 1);
memcpy (cp, vm->exec_result.u.vstring->data, vm->exec_result.u.vstring->len);
cp[vm->exec_result.u.vstring->len] = '\\0';
return cp;
");
}
else if (this.return_type == tDOUBLE)
stream.write (" return vm->exec_result.u.vfloat;\n");
else if (this.return_type == tINT)
stream.write (" return vm->exec_result.u.vinteger;\n");
}
stream.write ("}\n");
}
Func.prototype.print_c = Func$print_c;
function Func$compile ()
{
/* Create the byte-code for this function. */
var flags = 0;
if (false)
flags |= JSC$FLAG_VERBOSE;
if (opt_debug)
flags |= JSC$FLAG_GENERATE_DEBUG_INFO;
flags |= (JSC$FLAG_OPTIMIZE_PEEPHOLE
| JSC$FLAG_OPTIMIZE_JUMPS
| JSC$FLAG_OPTIMIZE_BC_SIZE);
flags |= JSC$FLAG_WARN_MASK;
try
{
this.bc = JSC$compile_string (this.code, flags, null, null);
}
catch (error)
{
System.error (error, "\n");
System.exit (1);
}
}
Func.prototype.compile = Func$compile;
function Func$dump_bc (stream)
{
stream.write ("\nstatic unsigned char " + this.name + "_bc[] = {");
var i;
for (i = 0; i < this.bc.length; i++)
{
if ((i % 12) == 0)
stream.write ("\n ");
var item = this.bc[i].toString (16);
if (item.length == 1)
item = "0" + item;
stream.write (" 0x" + item + ",");
}
stream.write ("\n};\n");
}
Func.prototype.dump_bc = Func$dump_bc;
/*
* The Argument class to hold function argument definitions.
*/
function Argument ()
{
this.type = false;
this.copy_type = tIN;
this.staticp = false;
}
new Argument ();
function Argument$print ()
{
System.print (typename (this.copy_type), " ", typename (this.type),
" ", this.name);
}
Argument.prototype.print = Argument$print;
/*
* The .jsw file parsing.
*/
function parse ()
{
var token;
var func;
headers ();
while ((token = get_token ()) != tEOF)
{
if (token != tFUNCTION)
syntax_error ();
func = new Func ();
/* Possible return type. */
token = get_token ();
if (is_type_token (token))
{
if (token == tSTRING)
{
System.error (input_file, ":", linenum,
": the function return value can't be `string'\n");
System.exit (1);
}
func.return_type = token;
token = get_token ();
}
else
func.return_type = tVOID;
/* The name of the function. */
if (token != tIDENTIFIER)
syntax_error ();
if (!valid_c_identifier_re.test (token_value))
{
System.error (input_file, ":", linenum,
": function name is not a valid C identifier `",
token_value, "'\n");
System.exit (1);
}
func.name = token_value;
/* Arguments. */
token = get_token ();
if (token != #'(')
syntax_error ();
var args = new Array ();
token = get_token ();
while (token != #')')
{
var arg = new Argument ();
while (token != tIDENTIFIER)
{
if (token == tEOF)
syntax_error ();
if (is_type_token (token))
arg.type = token;
else if (is_copy_type_token (token))
arg.copy_type = token;
else if (token == tSTATIC)
arg.staticp = true;
else
syntax_error ();
token = get_token ();
}
if (!valid_c_identifier_re.test (token_value))
{
System.error (input_file, ":", linenum,
": argument name is not a valid C identifier `",
token_value, "'\n");
System.exit (1);
}
arg.name = token_value;
/* Check some validity conditions. */
if (!arg.type)
{
System.error (input_file, ":", linenum,
": no type specified for argument `",
arg.name, "'\n");
System.exit (1);
}
if (arg.staticp)
{
if (arg.type != tCSTRING && arg.type != tSTRING)
{
System.error (input_file, ":", linenum,
": type `static' can only be used with `cstring' and `string' arguments\n");
System.exit (1);
}
if (arg.copy_type == tOUT)
System.error (input_file, ":", linenum,
": warning: type `static' is meaningful only with `in' and `inout' arguments\n");
}
args.push (arg);
token = get_token ();
if (token == #',')
token = get_token ();
}
func.args = args;
/* The opening '{' of the function body. */
token = get_token ();
if (token != #'{')
syntax_error ();
/* Get the function body. */
var code = new String ("");
while (true)
{
var line = ifp.readln ();
if (!line)
syntax_error ();
linenum++;
if (end_brace_re.test (line))
break;
code.append (line + "\n");
}
func.body = code;
func.generate_js ();
// func.print_js (ofp_js);
func.print_h (ofp_h, true);
func.print_c (ofp_c);
}
trailers ();
}
function get_token ()
{
var ch;
while ((ch = ifp.readByte ()) != -1)
{
if (ch == #' ' || ch == #'\t' || ch == #'\v' || ch == #'\r'
|| ch == #'\f')
continue;
if (ch == #'\n')
{
linenum++;
continue;
}
token_linenum = linenum;
if (ch == #'/' && peek_char () == #'*')
{
/* Multi line comment. */
ifp.readByte ();
while ((ch = ifp.readByte ()) != -1
&& (ch != #'*' || peek_char () != #'/'))
if (ch == #'\n')
linenum++;
/* Consume the peeked #'/' character. */
ifp.readByte ();
}
/* Identifiers and keywords. */
else if (JSC$lexer_is_identifier_letter (ch))
{
/* An identifier. */
var id = String.fromCharCode (ch);
while ((ch = ifp.readByte ()) != -1
&& (JSC$lexer_is_identifier_letter (ch)
|| JSC$lexer_is_decimal_digit (ch)))
id.append (File.byteToString (ch));
ifp.ungetByte (ch);
/* Keywords. */
if (id == "function")
return tFUNCTION;
/* Types. */
else if (id == "cstring")
return tCSTRING;
else if (id == "double")
return tDOUBLE;
else if (id == "int")
return tINT;
else if (id == "string")
return tSTRING;
else if (id == "void")
return tVOID;
else if (id == "in")
return tIN;
else if (id == "out")
return tOUT;
else if (id == "inout")
return tINOUT;
else if (id == "static")
return tSTATIC;
else
{
/* It really is an identifier. */
token_value = id;
return tIDENTIFIER;
}
}
/* Just return the character as-is. */
else
return ch;
}
/* EOF reached. */
return tEOF;
}
function peek_char ()
{
var ch = ifp.readByte ();
ifp.ungetByte (ch);
return ch;
}
function syntax_error ()
{
System.error (input_file, ":", linenum, ": syntax error\n");
System.exit (1);
}
function headers ()
{
var stream;
/* The header file. */
stream = ofp_h;
header_banner (stream);
var ppname = path_to_ppname (header_file);
stream.write ("\n#ifndef " + ppname
+ "\n#define " + ppname + "\n");
/* The C file. */
stream = ofp_c;
header_banner (stream);
stream.write ("\n#include <jsint.h>\n");
if (!opt_reentrant)
{
stream.write ("
/*
* This global interpreter handle can be removed with " + program + "'s
* option -r, --reentrant.
*/
");
stream.write ("extern JSInterpPtr jswrap_interp;\n");
}
if (opt_no_error_handler)
{
stream.write ("
/* Prototype for the error handler of the JS runtime errors. */
");
stream.write ("void jswrap_error (JSInterpPtr interp, char *error);\n");
}
else
{
/* Define the default jswrap_error() function. */
stream.write ("
/*
* This is the default error handler for the JS runtime errors. The default
* handler can be removed with " + program + "'s option -n, --no-error-handler.
* In this case, your code must define the handler function.
*/
");
stream.write ("\
static void
jswrap_error (JSInterpPtr interp, char *error)
{
const char *cp;
fprintf (stderr, \"JS runtime error: %s\", error);
cp = js_error_message (interp);
if (cp[0])
fprintf (stderr, \": %s\", cp);
fprintf (stderr, \"\\n\");
exit (1);
}
");
}
stream.write ("
/*
* The global function definitions.
*/
");
}
function header_banner (stream)
{
stream.write ("/* This file is automatically generated from `"
+ input_file + "' by " + program + ". */\n");
}
path_to_ppname_re = new RegExp ("[^A-Za-z_0-9]", "g");
function path_to_ppname (path)
{
var str = path.toUpperCase ().replace (path_to_ppname_re, "_");
if (#'0' <= str[0] && str[0] <= #'9')
str = "_" + str;
return str;
}
function trailers ()
{
/* The header file. */
var stream = ofp_h;
stream.write ("\n#endif /* not " + path_to_ppname (header_file) + " */\n");
}
/*
Local variables:
mode: c
End:
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -