From 05c29118dffdafd8c577469100c8ae3401d571b8 Mon Sep 17 00:00:00 2001 From: "rogerl%netscape.com" Date: Tue, 15 Jun 1999 00:57:05 +0000 Subject: [PATCH] Changes to get traditional functions with args. working --- js/js2/java/Environment.java | 22 - js/js2/java/FunctionNode.java | 18 - js/js2/java/JSGrammar.g | 1117 ------------------------------- js/js2/java/JSName.java | 27 - js/js2/java/JSObject.java | 66 -- js/js2/java/JSScope.java | 0 js/js2/java/JSValue.java | 218 ------ js/js2/java/NativeFunction.java | 19 - js/js2/java/NativeNumber.java | 18 - js/js2/java/TryNode.java | 47 -- 10 files changed, 1552 deletions(-) create mode 100644 js/js2/java/JSScope.java diff --git a/js/js2/java/Environment.java b/js/js2/java/Environment.java index 76a393adc33..e69de29bb2d 100644 --- a/js/js2/java/Environment.java +++ b/js/js2/java/Environment.java @@ -1,22 +0,0 @@ - -import java.util.Hashtable; - -class Environment { - - JSObject scope = new JSObject("globals", null); - - void enterNewScope(JSObject newScope) - { - - } - - String print() - { - StringBuffer result = new StringBuffer("Globals contents :\n"); - result.append(scope.toString()); - return result.toString(); - } - - JSValue resultValue; - -} \ No newline at end of file diff --git a/js/js2/java/FunctionNode.java b/js/js2/java/FunctionNode.java index 75dc34a1f12..e69de29bb2d 100644 --- a/js/js2/java/FunctionNode.java +++ b/js/js2/java/FunctionNode.java @@ -1,18 +0,0 @@ -class FunctionNode extends ExpressionNode { - - FunctionNode(JSIdentifier aName, ControlNodeGroup aBody) - { - fn = new NativeFunction(aBody.getHead()); - name = aName; - } - - JSValue eval(Environment theEnv) - { - theEnv.scope.putProp(theEnv, name, fn); - return fn; - } - - JSString name; - NativeFunction fn; - -} \ No newline at end of file diff --git a/js/js2/java/JSGrammar.g b/js/js2/java/JSGrammar.g index 78eb2fc33d1..e69de29bb2d 100644 --- a/js/js2/java/JSGrammar.g +++ b/js/js2/java/JSGrammar.g @@ -1,1117 +0,0 @@ -/* - TODO: - - * Add semantic feedback to lexer for: - * JS 1.x regexps - * Capturing blocks that have syntax errors - * Add semicolon abbreviation - * Ensure that optional function parameters do not precede required function parameters -*/ - -{ -import java.io.*; -// Test program -class TestMain { - public static void main(String[] args) { - try { - JSLexer lexer = new JSLexer(new DataInputStream(System.in)); - JSParser parser = new JSParser(lexer); - parser.program(); - } catch(Exception e) { - System.err.println("exception: "+e); - } - } -} -} - -class JSParser extends Parser; - -options { -// k = 2; // two token lookahead - tokenVocabulary=JS; // Call its vocabulary "JS" - codeGenMakeSwitchThreshold = 2; // Some optimizations - codeGenBitsetTestThreshold = 3; -// defaultErrorHandler = false; // Don't generate parser error handlers -// buildAST = true; -} - -{ - // Possible scopes for parsing - static final int TopLevelScope = 0; - static final int ClassScope = 1; - static final int BlockScope = 2; - - int currentScope = TopLevelScope; // stashing here rather than passing all the way down the parser -} - -// ********* Identifiers ********** -identifier returns [JSIdentifier e] - { e = null; } - : opI:IDENT { e = new JSIdentifier(opI.getText()); } - | "version" { e = new JSIdentifier("version"); } - | "override" { e = new JSIdentifier("override"); } - | "method" { e = new JSIdentifier("method"); } - | "getter" { e = new JSIdentifier("getter"); } - | "setter" { e = new JSIdentifier("setter"); } - | "traditional" { e = new JSIdentifier("traditional"); } - | "constructor" { e = new JSIdentifier("constructor"); } - ; - -qualified_identifier returns [ExpressionNode e] - { e = null; ExpressionNode e2 = null; } - : (e2 = parenthesized_expression)? ("::" e = identifier { e = new BinaryNode("::", e2, e); } )+ - | e = identifier ("::" e2 = identifier { e = new BinaryNode("::", e, e2); } )* - ; - -qualified_identifier_or_parenthesized_expression[boolean isLeftMostId] returns [ExpressionNode e] - { e = null; ExpressionNode e2 = null; JSIdentifier id = null; } - : (e = parenthesized_expression | id = identifier { if (isLeftMostId) e = new JSName(id, currentScope); else e = id; } ) ("::" e2 = identifier { e = new BinaryNode("::", e, e2); } )* - ; - -// ********* Primary Expressions ********** -primary_expression[boolean initial] returns [ExpressionNode e] - { e = null; } - : {!initial}? - ( - e = function_expression - | e = object_literal - ) - | e = simple_expression - ; - -simple_expression returns [ExpressionNode e] - { e = null; } - : "null" { e = new JSObject("null", null); } // XXX - | "true" { e = JSBoolean.JSTrue; } - | "false" { e = JSBoolean.JSFalse; } - | opN:NUMBER { e = new JSDouble(opN.getText()); } - | opS:STRING { e = new JSString(opS.getText()); } - | "this" { e = new JSObject("this", null); } // XXX - | "super" { e = new JSObject("super", null); } // XXX - | e = qualified_identifier_or_parenthesized_expression[true] - | opR:REGEXP { e = new JSObject(opR.getText(), null); } // XXX - | e = array_literal - ; - -parenthesized_expression returns [ExpressionNode e] - { e = null; } - : "(" e = expression[false, true] ")" ; - -// ********* Function Expressions ********** -function_expression returns [ExpressionNode e] - { e = null; } - : e = function[false] - ; - -// ********* Object Literals ********** -object_literal returns [ExpressionNode e] - { e = null; } - : "{" (e = field_list)? "}" ; - -field_list returns [ExpressionNode e] - { e = null; ExpressionNode e2 = null; } - : e = literal_field ("," e2 = literal_field { e = new BinaryNode(",", e, e2); } )* ; - -literal_field returns [ExpressionNode e] - { e = null; ExpressionNode e2 = null; } - : e = qualified_identifier ":" e = assignment_expression[false, true] { e = new BinaryNode(":", e, e2); } - ; - -// ********* Array Literals ********** -array_literal returns [ExpressionNode e] - { e = null; } - : "[" (element_list)? "]" ; - -element_list - : literal_element ("," literal_element)* ; - -literal_element - { ExpressionNode e = null; } - : e = assignment_expression[false, true] ; - -// ********* Postfix Unary Operators ********** -postfix_expression[boolean initial] returns [ExpressionNode e] - { e = null; ExpressionNode r = null; } - : - ( e = primary_expression[initial] - | e = new_expression - ) - ( - r = member_operator { e = new BinaryNode(((UnaryNode)r).getOperator(), e, ((UnaryNode)r).getChild()); } - | r = arguments { e = new BinaryNode("()", e, r); } - | "++" { e = new UnaryNode("++", e); } - | "--" { e = new UnaryNode("--", e); } - )* - ; - -new_expression returns [ExpressionNode e] - { e = null; } - : "new" - ( - e = new_expression - | ( - e = primary_expression[false] - ( - // There's an ambiguity here: - // Consider the input 'new f.x'. Is that equivalent to '(new f).x' or 'new (f.x)' ? - // Assume the latter by using ANTLR's default behavior of consuming input as - // soon as possible and quell the resultant warning. - options { - warnWhenFollowAmbig=false; - } - : e = member_operator - )* - ) - ) - ( - // There's an ambiguity here: - // Consider the input 'new F(arg)'. Is that equivalent to '(new F)(arg)' or does - // it construct an instance of F, passing 'arg' as an argument to the constructor ? - // Assume the latter by using ANTLR's default behavior of consuming input as - // soon as possible and quell the resultant warning. - options { - warnWhenFollowAmbig=false; - } - : e = arguments - )* - ; - -member_operator returns [ExpressionNode e] - { e = null; } - : "[" e = argument_list "]" { e = new UnaryNode("[]", e); } - | DOT e = qualified_identifier_or_parenthesized_expression[false] { e = new UnaryNode(".", e); } - | "@" e = qualified_identifier_or_parenthesized_expression[false] { e = new UnaryNode("@", e); } - ; - -arguments returns [ExpressionNode e] - { e = null; } - : "(" e = argument_list ")" ; - -argument_list returns [ExpressionNode e] - { e = null; ExpressionNode e2 = null; } - : (e = assignment_expression[false, true] ("," e2 = assignment_expression[false, true] { e = new BinaryNode(",", e, e2); } )*)? ; - -// ********* Prefix Unary Operators ********** -unary_expression[boolean initial] returns [ExpressionNode e] - { e = null; } - : e = postfix_expression[initial] - | "delete" e = postfix_expression[false] { e = new UnaryNode("delete", e); } - | "typeof" e = unary_expression[false] { e = new UnaryNode("typeof", e); } - | "eval" e = unary_expression[false] { e = new UnaryNode("eval", e); } - | "++" e = postfix_expression[false] { e = new UnaryNode("++", e); } - | "--" e = postfix_expression[false] { e = new UnaryNode("--", e); } - | "+" e = unary_expression[false] { e = new UnaryNode("+", e); } - | "-" e = unary_expression[false] { e = new UnaryNode("-", e); } - | "~" e = unary_expression[false] { e = new UnaryNode("~", e); } - | "!" e = unary_expression[false] { e = new UnaryNode("!", e); } - ; - -// ********* Multiplicative Operators ********** -multiplicative_expression[boolean initial] returns [ExpressionNode e] - { e = null; ExpressionNode r = null; } - : e = unary_expression[initial] ( - ("*" r = unary_expression[false] { e = new ArithmeticNode("*", e, r); } ) - | ("/" r = unary_expression[false] { e = new ArithmeticNode("/", e, r); } ) - | ("%" r = unary_expression[false] { e = new ArithmeticNode("%", e, r); } ) - )* - ; - -// ********* Additive Operators ********** -additive_expression[boolean initial] returns [ExpressionNode e] - { e = null; ExpressionNode r = null; } - : e = multiplicative_expression[initial] ( - ("+" r = multiplicative_expression[false] { e = new ArithmeticNode("+", e, r); } ) - | ("-" r = multiplicative_expression[false] { e = new ArithmeticNode("-", e, r); } ) - )* - ; - -// ********* Bitwise Shift Operators ********** -shift_expression[boolean initial] returns [ExpressionNode e] - { e = null; ExpressionNode r = null; } - : e = additive_expression[initial] ( - ("<<" r = additive_expression[false] { e = new BitwiseNode("<<", e, r); } ) - | (">>" r = additive_expression[false] { e = new BitwiseNode(">>", e, r); } ) - | (">>>" r = additive_expression[false] { e = new BitwiseNode(">>>", e, r); } ) - )* - ; - -// ********* Relational Operators ********** -relational_operator[boolean allowIn] returns [String s] - { s = null; } - : {allowIn}? "in" { s = "in"; } - | "<" { s = "<"; } - | ">" { s = ">"; } - | "<=" { s = "<="; } - | ">=" { s = ">="; } - | "instanceof" { s = "instanceof"; } - ; - -relational_expression[boolean initial, boolean allowIn] returns [ExpressionNode e] - { e = null; ExpressionNode r = null; String op = null; } - : e = shift_expression[initial] - ( - // ANTLR reports an ambiguity here because the FOLLOW set of a relational_expression - // includes the "in" token (from the for-in statement), but there's no real ambiguity - // here because the 'allowIn' semantic predicate is used to prevent the two from being - // confused. - options { warnWhenFollowAmbig=false; }: - op = relational_operator[allowIn] r = shift_expression[false] { e = new RelationalNode(op, e, r); } - )* - ; - -// ********* Equality Operators ********** -equality_expression[boolean initial, boolean allowIn] returns [ExpressionNode e] - { e = null; ExpressionNode r = null; } - : e = relational_expression[initial, allowIn] - ( - ("==" r = relational_expression[false, allowIn]) { e = new RelationalNode("==", e, r); } - | ("!=" r = relational_expression[false, allowIn]) { e = new RelationalNode("!=", e, r); } - | ("===" r = relational_expression[false, allowIn]) { e = new RelationalNode("===", e, r); } - | ("!==" r = relational_expression[false, allowIn]) { e = new RelationalNode("!===", e, r); } - )* - ; - -// ********* Binary Bitwise Operators ********** -bitwise_and_expression[boolean initial, boolean allowIn] returns [ExpressionNode e] - { e = null; ExpressionNode r = null; } - : e = equality_expression[initial, allowIn] - ("&" r = equality_expression[false, allowIn] { e = new BitwiseNode("&", e, r); } )* - ; - -bitwise_xor_expression[boolean initial, boolean allowIn] returns [ExpressionNode e] - { e = null; ExpressionNode r = null; } - : e = bitwise_and_expression[initial, allowIn] - ("^" (r = bitwise_and_expression[false, allowIn] { e = new BitwiseNode("^", e, r); } | "*" | "?"))* - ; - -bitwise_or_expression[boolean initial, boolean allowIn] returns [ExpressionNode e] - { e = null; ExpressionNode r = null; } - : e = bitwise_xor_expression[initial, allowIn] - ("|" (r = bitwise_xor_expression[false, allowIn] { e = new BitwiseNode("|", e, r); } | "*" | "?"))* - ; - -// ********* Binary Logical Operators ********** -logical_and_expression[boolean initial, boolean allowIn] returns [ExpressionNode e] - { e = null; ExpressionNode r = null; } - : e = bitwise_or_expression[initial, allowIn] - ("&&" r = bitwise_or_expression[false, allowIn] { e = new LogicalNode("&&", e, r); } )* - ; - -logical_or_expression[boolean initial, boolean allowIn] returns [ExpressionNode e] - { e = null; ExpressionNode r = null; } - : e = logical_and_expression[initial, allowIn] - ("||" r = logical_and_expression[false, allowIn] { e = new LogicalNode("||", e, r); } )* - ; - -// ********* Conditional Operators ********** -conditional_expression[boolean initial, boolean allowIn] returns [ExpressionNode e] - { e = null; ExpressionNode e1 = null; ExpressionNode e2 = null; } - : e = logical_or_expression[initial, allowIn] - // There's an ambiguity here: - // Consider the input 'a ? b : c ? d : e'. Is that equivalent to '(a ? b : c) ? d : e' or - // should it be interpreted as 'a ? b : (c ? d : e)' ? - // Assume the latter by using ANTLR's default behavior of consuming input as - // soon as possible and quell the resultant warning. - ( - options {warnWhenFollowAmbig=false;} - : "?" e1 = assignment_expression[false, allowIn] ":" e2 = assignment_expression[false, allowIn] - { - e = new BinaryNode("?", e, new BinaryNode(":", e1, e2)); - } - )* - ; - -non_assignment_expression[boolean initial, boolean allowIn] returns [ExpressionNode e] - { e = null; ExpressionNode e1 = null; ExpressionNode e2 = null; } - : e = logical_or_expression[initial, allowIn] - // There's an ambiguity here: - // Consider the input 'a ? b : c ? d : e'. Is that equivalent to '(a ? b : c) ? d : e' or - // should it be interpreted as 'a ? b : (c ? d : e)' ? - // Assume the latter by using ANTLR's default behavior of consuming input as - // soon as possible and quell the resultant warning. - ( - options { - warnWhenFollowAmbig=false; - } - : "?" e1 = non_assignment_expression[false, allowIn] ":" e2 = non_assignment_expression[false, allowIn] - { - e = new BinaryNode("?", e, new BinaryNode(":", e1, e2)); - } - )* - ; - -// ********* Assignment Operators ********** - -// FIXME - Can we get rid of lookahead ? -assignment_expression[boolean initial, boolean allowIn] returns [ExpressionNode e] - { e = null; ExpressionNode p = null; ExpressionNode a = null; String op = null; } - : (postfix_expression[initial] "=") => - (p = postfix_expression[initial] "=" a = assignment_expression[false, allowIn] { e = new AssignmentNode("=", p, a); } ) - | (postfix_expression[initial] compound_assignment) => - (p = postfix_expression[initial] op = compound_assignment a = assignment_expression[false, allowIn] { e = new AssignmentNode(op, p, a); } ) - | e = conditional_expression[false, allowIn] - ; - -compound_assignment returns [String op] - { op = null; } - : "*=" { op = "*="; } - | "/=" { op = "/="; } - | "%=" { op = "%="; } - | "+=" { op = "+="; } - | "-=" { op = "-="; } - | "<<=" { op = "<<="; } - | ">>=" { op = ">>="; } - | ">>>=" { op = ">>>="; } - | "&=" { op = "&="; } - | "^=" { op = "^="; } - | "|=" { op = "|="; } - ; - -// ********* Expressions ********** -expression[boolean initial, boolean allowIn] returns [ExpressionNode e] - { e = null; ExpressionNode e2 = null; } - : e = assignment_expression[initial, allowIn] ("," e2 = assignment_expression[false, allowIn] { e = new BinaryNode(",", e, e2); } )* - ; - -optional_expression returns [ExpressionNode e] - { e = null; } - : ( e = expression[false, true])? - ; - -// ********* Type Expressions ********** -type_expression[boolean initial, boolean allowIn] - { ExpressionNode e = null; } - : e = non_assignment_expression[initial, allowIn] - ; - -// ********* Statements ********** - -statement[int scope, boolean non_empty, ControlNodeGroup container] - : (definition[scope, container]) => definition[scope, container] - | code_statement[non_empty, container, null] - ; - -code_statement[boolean non_empty, ControlNodeGroup container, String label] - : empty_statement[non_empty] - -// Bogus predicate required to eliminate ANTLR nondeterminism warning -// on lookahead of '{' between expression_statement and block, even -// though the symantic predicate in the primary_expression rule disambiguates -// the two. - | ("{") => block[BlockScope, container] - | (identifier ":") => labeled_statement[non_empty, container] - | expression_statement[container] semicolon - | if_statement[non_empty, container] - | switch_statement[container] - | do_statement[container, label] semicolon - | while_statement[non_empty, container, label] - | for_statement[non_empty, container, label] - | with_statement[non_empty, container] - | continue_statement[container] semicolon - | break_statement[container] semicolon - | return_statement[container] semicolon - | throw_statement[container] semicolon - | try_statement[container] - | import_statement[non_empty] - ; - -semicolon -// FIXME - Add abbreviation - : ";" - ; - -// ********* Empty Statement ********** -// FIXME -empty_statement[boolean non_empty] - : ";" - ; - -// ********* Expression Statement ********** -expression_statement[ControlNodeGroup container] - { ExpressionNode e = null; } - : e = expression[true, true] - { - container.add(new ControlNode(e)); - } - - ; - -// ********* Block ********** -block[int scope, ControlNodeGroup container] - { ControlNodeGroup subContainer = new ControlNodeGroup(); int oldScope = currentScope; currentScope = scope; } - : "{" - statements[scope, subContainer] - { - container.add(subContainer); // necessary ? - scope = oldScope; - } - "}" - ; - -// FIXME -statements[int scope, ControlNodeGroup container] - : statement[scope, false, container] - ( statement[scope, false, container] )* - ; - -// ********* Labeled Statements ********** -labeled_statement[boolean non_empty, ControlNodeGroup container] - { ExpressionNode e = null; } - : e = identifier ":" code_statement[non_empty, container, ((JSIdentifier)e).s] - ; - -if_statement[boolean non_empty, ControlNodeGroup container] - { ConditionalNode condition = null; ExpressionNode e = null; } - : "if" e = parenthesized_expression - { - condition = new ConditionalNode(e); - container.add(condition); - } - code_statement[non_empty, container, null] - { - condition.moveNextToTrue(); - container.addTail(condition); - } - ( - // Standard if/else ambiguity - options { warnWhenFollowAmbig=false; }: - "else" code_statement[non_empty, container, null] - )? - ; - -// ********* Switch statement ********** -switch_statement[ControlNodeGroup container] - { ExpressionNode e = null; SwitchNode s = null; ControlNodeGroup c = new ControlNodeGroup(); } - : "switch" e = parenthesized_expression - { - s = new SwitchNode(e); - } - "{" (case_groups[s, c])? "}" - { - container.add(s); - c.shiftBreakTails(null); - container.addTails(c); - } - ; - -case_groups[SwitchNode s, ControlNodeGroup container] - : (case_group[s, container])+ - ; - -case_group[SwitchNode s, ControlNodeGroup container] - { ExpressionNode e = null; ControlNodeGroup c = new ControlNodeGroup(); } - : ( e = case_guard)+ (code_statement[true, c, null])+ - { - s.addCase(e, c.getHead()); - container.add(c); - } - ; - -case_guard returns [ExpressionNode e] - { e = null; } - : "case" e = expression[false, true] ":" - | "default" ":" - ; - -// FIXME -case_statements - { ControlNodeGroup c = new ControlNodeGroup(); } - : ( code_statement[false, c, null] )+ - ; - -// ********* Do-While statement ********** -do_statement[ControlNodeGroup container, String label] - { ControlNodeGroup body = new ControlNodeGroup(); ExpressionNode e = null; } - : "do" code_statement[true, body, null] "while" e = parenthesized_expression - { - ConditionalNode condition = new ConditionalNode(e, body.getHead()); - body.fixTails(condition); - body.fixContinues(condition, label); - body.shiftBreakTails(label); - container.add(body); - } - ; - -// ********* While statement ********** -while_statement[boolean non_empty, ControlNodeGroup container, String label] - { ExpressionNode e = null; ControlNodeGroup body = new ControlNodeGroup(); } - : "while" e = parenthesized_expression code_statement[non_empty, body, null] - { - ConditionalNode condition = new ConditionalNode(e, body.getHead()); - body.fixTails(condition); - body.fixContinues(condition, label); - body.shiftBreakTails(label); - body.setHead(condition); - container.add(body); - } - ; - -// ********* For statement ********** -for_statement[boolean non_empty, ControlNodeGroup container, String label] - { - ExpressionNode ei = null; - ExpressionNode ec = null; - ExpressionNode en = null; - ControlNodeGroup body = new ControlNodeGroup(); - } - : "for" "(" - ( - (for_initializer ";") => ei = for_initializer ";" ec = optional_expression ";" en = optional_expression - | ei = for_in_binding "in" ec = expression[false, true] - ) - ")" - code_statement[non_empty, body, null] - { - container.add(new ControlNode(ei)); - - ControlNode increment = new ControlNode(en); - body.fixContinues(increment, label); - body.add(increment); - - ControlNode condition = new ConditionalNode(ec, body.getHead()); - body.fixTails(condition); - body.shiftBreakTails(label); - body.setHead(condition); - - container.add(body); - - } - ; - -for_initializer returns [ExpressionNode e] - { e = null; } - : ( - e = expression[false, true] - | ("var" | "const") variable_binding_list[false] - )? - ; - -for_in_binding returns [ExpressionNode e] - { e = null; } - : ( - e = postfix_expression[false] - | ("var" | "const") variable_binding_list[false] - ) - ; - -// ********* With statement ********** -with_statement[boolean non_empty, ControlNodeGroup container] - { ExpressionNode e = null; ControlNodeGroup body = new ControlNodeGroup(); } - : "with" e = parenthesized_expression code_statement[non_empty, body, null] - { - container.add(new ControlNode(e)); - container.add(body); - } - ; - -// ********* Continue and Break statement ********** -continue_statement [ControlNodeGroup container] - { ExpressionNode e = null; } - : "continue" (e = identifier)? - { - container.addContinue(new ControlNode(e)); - } - ; - -break_statement [ControlNodeGroup container] - { ExpressionNode e = null; } - : "break" (e = identifier)? - { - container.addBreak(new ControlNode(e)); - } - ; - -// ********* Return statement ********** -return_statement [ControlNodeGroup container] - { ExpressionNode e = null; } - : "return" e = optional_expression - { - container.add(new ControlNode(e)); - } - ; - -// ********* Throw statement ********** -throw_statement [ControlNodeGroup container] - { ExpressionNode e = null; } - : "throw" e = expression[false, true] - { - container.add(new ThrowNode(e)); - } - ; - -// ********* Try statement ********** -try_statement [ControlNodeGroup container] - { - TryNode t = null; - ControlNodeGroup tryBody = new ControlNodeGroup(); - ControlNodeGroup finallyBody = new ControlNodeGroup(); - } - : "try" block[BlockScope, tryBody] - { - t = new TryNode(tryBody.getHead()); - } - (catch_clause[t])* - ("finally" block[BlockScope, finallyBody] { t.addFinally(finallyBody.getHead()); } )? - { - container.add(t); - } - ; - -catch_clause [TryNode t] - { ControlNodeGroup catchCode = new ControlNodeGroup(); ExpressionNode e = null; } - : "catch" "(" e = typed_identifier[true] ")" block[BlockScope, catchCode] - { - t.addCatchClause(e, catchCode.getHead()); - } - ; - -// ********* Import statement ********** -import_statement[boolean non_empty] - { ControlNodeGroup c = new ControlNodeGroup(); } - : "import" import_list - ( - ";" - | block[BlockScope, c] ("else" code_statement[non_empty, c, null]) - ) - ; - -import_list - : import_item ("," import_item)* - ; - -import_item - { ExpressionNode e = null; } - : (identifier "=") => e = identifier "=" import_source - | import_source - | "protected" e = identifier "=" import_source - ; - -import_source - { ExpressionNode e = null; } - : e = non_assignment_expression[false, false] (":" Version) - ; - -// ********* Definitions ********** -definition[int scope, ControlNodeGroup container] - : visibility global_definition[container] - | local_definition[scope, container] - ; - -global_definition[ControlNodeGroup container] - { ExpressionNode e = null; } - : version_definition semicolon - | variable_definition semicolon - - // Syntactic predicate is required to disambiguate between getter/setter methods - // and getter/setter functions - | ("traditional" | "function" | (("getter" | "setter") "function")) - => e = function_definition { container.add(new ControlNode(e)); } - | member_definition - | class_definition - ; - -local_definition[int scope, ControlNodeGroup container] - { ExpressionNode e = null; } - : {scope == TopLevelScope || scope == ClassScope}? (class_definition | member_definition) - | variable_definition semicolon - | e = function_definition { container.add(new ControlNode(e)); } - ; - -// ********* Visibility Specifications ********** -visibility - : "private" - | "package" - | "public" versions_and_renames - ; - -// ********* Versions ********** - -// FIXME -versions_and_renames: - version_range_and_alias ("," version_range_and_alias)* - ; - -version_range_and_alias - { ExpressionNode e = null; } - : version_range (":" e = identifier) - ; - -version_range - : (version)? (".." (version)?) - ; - -version: STRING ; - -// ********* Version Definition ********** -version_definition - : "version" version - ( - ">" version_list - "=" version - )? - ; - -version_list - : version ("," version)* - ; - -// ********* Variable Definition ********** -variable_definition - : ("var" | "const") variable_binding_list[true] - ; - -variable_binding_list[boolean allowIn] - : variable_binding[allowIn] ("," variable_binding[allowIn])* - ; - -variable_binding[boolean allowIn] - { ExpressionNode e = null; } - : e = typed_identifier[allowIn] ("=" e = assignment_expression[false, allowIn])? - ; - -typed_identifier[boolean allowIn] returns [ExpressionNode e] - { e = null; } - : (type_expression[false, allowIn] identifier) => type_expression[false, allowIn] e = identifier - | e = identifier - ; - -// ********* Function Definition ********** -function_definition returns [ExpressionNode e] - { e = null; } - : e = named_function - | "getter" e = named_function - | "setter" e = named_function - | e = traditional_function - ; - -anonymous_function returns [ExpressionNode e] - { e = null; } - : e = function[false] - ; - -named_function returns [ExpressionNode e] - { e = null; } - : e = function[true] - ; - -function[boolean nameRequired] returns [ExpressionNode e] - { e = null; ControlNodeGroup body = new ControlNodeGroup(); } - : "function" - ( - {nameRequired}? e = identifier - | e = identifier - ) - function_signature block[BlockScope, body] - ; - -function_signature - : parameter_signature result_signature - ; - -parameter_signature - : "(" parameters ")" - ; - -parameters - : (parameter ("," parameter)*)? (rest_parameter)? - ; - -// FIXME - Required parameters cannot follow optional parameters -parameter - { ExpressionNode e = null; } - : e = typed_identifier[true] ("=" (e = assignment_expression[false, true])? )? - ; - -rest_parameter - { ExpressionNode e = null; } - : "..." (e = identifier)? - ; - - -result_signature - : ( - // ANTLR reports an ambiguity here because the FOLLOW set of a parameter_signature - // includes the "{" token (from the block that contains a function's code), but there's - // no real ambiguity here because the 'allowIn' semantic predicate is used to prevent the - // two from being confused. - options { warnWhenFollowAmbig=false; }: - type_expression[true, true] - )? - ; - -traditional_function returns [ExpressionNode e] - { e = null; JSIdentifier id = null; ControlNodeGroup c = new ControlNodeGroup(); } - : "traditional" "function" id = identifier "(" traditional_parameter_list ")" block[BlockScope, c] - { e = new FunctionNode(id, c); } - ; - -traditional_parameter_list - { ExpressionNode e = null; ExpressionNode e2 = null; } - : (e = identifier ("," e2 = identifier { e = new BinaryNode(",", e, e2); } )* )? - ; - -// ********* Class Member Definitions ********** -member_definition - : field_definition semicolon - | method_definition - | constructor_definition - ; - -field_definition - : "field" variable_binding_list[true] - ; - -method_definition - { ExpressionNode e = null; ControlNodeGroup c = new ControlNodeGroup(); } - : method_prefix e = identifier function_signature ( block[BlockScope, c] | semicolon) - ; - -method_prefix - : ("final")? ("override")? ("getter" | "setter")? "method" - ; - -constructor_definition - { ExpressionNode e = null; ControlNodeGroup c = new ControlNodeGroup(); } - : "constructor" ("new" | e = identifier) parameter_signature block[BlockScope, c] - ; - -// ********* Class Definition ********** -class_definition - { ExpressionNode e = null; ControlNodeGroup c = new ControlNodeGroup(); } - : "class" - ( - "extends" type_expression[true, true] - | e = identifier ("extends" type_expression[true, true])? - ) - block[ClassScope, c] - ; - -// ********* Programs ********** -// Start symbol for JS programs -program returns [ControlNodeGroup contents] - { contents = new ControlNodeGroup(); } - : statements[TopLevelScope, contents] - ; - -// ************************************************************************************************ -class JSLexer extends Lexer; - -// Lexer options -options { - tokenVocabulary=JS; // Name the token vocabulary - testLiterals=false; // Don't automatically test every token to see if it's a literal. - // Rather, test only the ones that we explicitly indicate. - k=4; // Set number of lookahead characters -} - -// Operators -OPERATORS - options {testLiterals=true;} - : '?' - | '(' - | ')' - | '[' - | ']' - | '{' - | '}' - | ':' - | ',' -// | '.' FIXME - conflict w/ NUMBER - | '=' - | "==" - | '!' - | '~' - | "!=" -// | '/' FIXME - conflict w/ REGEXP -// | "/=" - | '+' - | "+=" - | "++" - | '-' - | "-=" - | "--" - | '*' - | "*=" - | '%' - | "%=" - | ">>" - | ">>=" - | ">>>" - | ">>>=" - | ">=" - | ">" - | "<<" - | "<<=" - | "<=" - | '<' - | '^' - | "^=" - | '|' - | "|=" - | "||" - | '&' - | "&=" - | "&&" - | ";" -// | "..." - ; - -// Whitespace - mostly ignored -WHITESPACE: - ( '\t' // Tab - | '\u000B' // Vertical Tab - | '\u000C' // Form Feed - | ' ' // Space - | LINE_TERMINATOR // subrule for newlines - ) - { $setType(Token.SKIP); } - ; - -// Line Terminator -protected -LINE_TERMINATOR: - ( "\r\n" // Evil DOS - | '\r' // Macintosh - | '\n' // Unix (the right way) - ) - { newline(); } - ; - -// Single-line comments -SINGLE_LINE_COMMENT - : "//" - (~('\n'|'\r'))* - {$setType(Token.SKIP);} - ; - -// Multiple-line comments -MULTI_LINE_COMMENT - : "/*" - ( /* '\r' '\n' can be matched in one alternative or by matching - '\r' in one iteration and '\n' in another. I am trying to - handle any flavor of newline that comes in, but the language - that allows both "\r\n" and "\r" and "\n" to all be valid - newline is ambiguous. Consequently, the resulting grammar - must be ambiguous. I'm shutting this warning off. - */ - options { - generateAmbigWarnings=false; - } - : - { LA(2)!='/' }? '*' - | '\r' '\n' {newline();} - | '\r' {newline();} - | '\n' {newline();} - | ~('*'|'\n'|'\r') - )* - "*/" - {$setType(Token.SKIP);} - ; - -// string literals -STRING - : '"' (ESC|~('"'|'\\'))* '"' // Double-quoted string - | '\'' (ESC|~('\''|'\\'))* '\'' // Single-quoted string - ; - -// escape sequence -- note that this is protected; it can only be called -// from another lexer rule -- it will not ever directly return a token to -// the parser -// There are various ambiguities hushed in this rule. The optional -// '0'...'9' digit matches should be matched here rather than letting -// them go back to STRING_LITERAL to be matched. ANTLR does the -// right thing by matching immediately; hence, it's ok to shut off -// the FOLLOW ambig warnings. -protected -ESC - : '\\' - ( 'b' - | 't' - | 'n' - | 'f' - | 'r' - | '"' - | '\'' - | '\\' - | 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT - | ('0'..'3') - ( - options { - warnWhenFollowAmbig = false; - } - : ('0'..'7') - ( - options { - warnWhenFollowAmbig = false; - } - : '0'..'7' - )? - )? - | ('4'..'7') - ( - options { - warnWhenFollowAmbig = false; - } - : ('0'..'7') - )? - ) - ; - - -// hexadecimal digit (again, note it's protected!) -protected -HEX_DIGIT - : ('0'..'9'|'A'..'F'|'a'..'f') - ; - -// a numeric literal -NUMBER - {boolean isDecimal=false;} - : '.' {$setType(DOT);} (('0'..'9')+ (EXPONENT)? { $setType(NUMBER); })? - | ( '0' {isDecimal = true;} // special case for just '0' - ( ('x'|'X') - ( // hex - // the 'e'|'E' and float suffix stuff look - // like hex digits, hence the (...)+ doesn't - // know when to stop: ambig. ANTLR resolves - // it correctly by matching immediately. It - // is therefor ok to hush warning. - options { - warnWhenFollowAmbig=false; - } - : HEX_DIGIT - )+ - | ('0'..'7')+ // octal - )? - | ('1'..'9') ('0'..'9')* {isDecimal=true;} // non-zero decimal - ) - - // only check to see if it's a float if looks like decimal so far - ( {isDecimal}? - ( '.' ('0'..'9')* (EXPONENT)? - | EXPONENT - )? - | // Empty - ) - ; - - -// A protected methods to assist in matching floating point numbers -protected -EXPONENT - : ('e'|'E') ('+'|'-')? ('0'..'9')+ - ; - -// An identifier. Note that testLiterals is set to true, so that -// after the rule is matched, the literals table is queried to see -// if the token is a literal or if it's really an identifer. -IDENT - options {testLiterals=true;} - : ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'$')* - ; - -// FIXME - this is a placeholder until lexical disambiguation is added between -// division and regexps. -REGEXP - : '/' (~('/'|'*'))+ '/' - ; diff --git a/js/js2/java/JSName.java b/js/js2/java/JSName.java index 39a294da583..e69de29bb2d 100644 --- a/js/js2/java/JSName.java +++ b/js/js2/java/JSName.java @@ -1,27 +0,0 @@ -class JSName extends ExpressionNode { - - JSName(JSIdentifier anID, int aScope) - { - id = anID; - scope = aScope; // this is the scope that the name was used in - } - - String print(String indent) - { - return indent + "JSName : " + id.s + ", scope : " + scope + "\n"; - } - - JSReference evalLHS(Environment theEnv) - { - return new JSReference(theEnv.scope, id); - } - - JSValue eval(Environment theEnv) - { - return theEnv.scope.getProp(theEnv, id); - } - - JSIdentifier id; - int scope; - -} \ No newline at end of file diff --git a/js/js2/java/JSObject.java b/js/js2/java/JSObject.java index 361fc410017..e69de29bb2d 100644 --- a/js/js2/java/JSObject.java +++ b/js/js2/java/JSObject.java @@ -1,66 +0,0 @@ - -import java.util.Hashtable; - -class JSObject extends JSValue { - - static JSObject JSUndefined = new JSObject("undefined", null); - - JSObject(String aValue, JSObject aPrototype) - { - value = aValue; - prototype = aPrototype; - } - - String print(String indent) - { - return indent + "JSObject : " + value + "\n"; - } - - public String toString() { - return value + contents.toString(); - } - - JSValue eval(Environment theEnv) - { - return this; - } - - JSValue typeof(Environment theEnv) { - if (this == JSUndefined) - return new JSString("undefined"); - else - return new JSString("object"); - } - - JSBoolean toJSBoolean(Environment theEnv) { - return JSBoolean.JSTrue; - } - - JSDouble toJSDouble(Environment theEnv) { - return toPrimitive(theEnv, "Number").toJSDouble(theEnv); - } - - JSValue getProp(Environment theEnv, JSString id) - { - Object v = contents.get(id.s); - if (v == null) - if (prototype == null) - return JSUndefined; - else - return prototype.getProp(theEnv, id); - else - return (JSValue)v; - } - - JSValue putProp(Environment theEnv, JSString id, JSValue rV) { - contents.put(id.s, rV); - return rV; - } - - - Hashtable contents = new Hashtable(); - - String value; - - JSObject prototype; -} \ No newline at end of file diff --git a/js/js2/java/JSScope.java b/js/js2/java/JSScope.java new file mode 100644 index 00000000000..e69de29bb2d diff --git a/js/js2/java/JSValue.java b/js/js2/java/JSValue.java index 3bcf454d665..e69de29bb2d 100644 --- a/js/js2/java/JSValue.java +++ b/js/js2/java/JSValue.java @@ -1,218 +0,0 @@ -class JSValue extends ExpressionNode { - - String print(String indent) - { - return indent + "JSValue\n"; - } - - JSReference evalLHS(Environment theEnv) - { - throw new RuntimeException("EvalLHS on non-lvalue"); - } - - JSValue eval(Environment theEnv) - { - throw new RuntimeException("Eval on JSValue"); - } - - JSValue unimplemented(String op) - { - throw new RuntimeException("unimplemented " + op + " called"); - } - - JSValue gt(Environment theEnv, JSValue rV) { - JSValue lV = toPrimitive(theEnv, "Number"); - rV = rV.toPrimitive(theEnv, "Number"); - if ((lV instanceof JSString) && (rV instanceof JSString)) - return lV.gt(theEnv, rV); - else - return lV.toJSDouble(theEnv).gt(theEnv, rV.toJSDouble(theEnv)); - } - - JSValue ge(Environment theEnv, JSValue rV) { - JSValue lV = toPrimitive(theEnv, "Number"); - rV = rV.toPrimitive(theEnv, "Number"); - if ((lV instanceof JSString) && (rV instanceof JSString)) - return lV.ge(theEnv, rV); - else - return lV.toJSDouble(theEnv).ge(theEnv, rV.toJSDouble(theEnv)); - } - - JSValue lt(Environment theEnv, JSValue rV) { - JSValue lV = toPrimitive(theEnv, "Number"); - rV = rV.toPrimitive(theEnv, "Number"); - if ((lV instanceof JSString) && (rV instanceof JSString)) - return lV.lt(theEnv, rV); - else - return lV.toJSDouble(theEnv).lt(theEnv, rV.toJSDouble(theEnv)); - } - - JSValue le(Environment theEnv, JSValue rV) { - JSValue lV = toPrimitive(theEnv, "Number"); - rV = rV.toPrimitive(theEnv, "Number"); - if ((lV instanceof JSString) && (rV instanceof JSString)) - return lV.le(theEnv, rV); - else - return lV.toJSDouble(theEnv).le(theEnv, rV.toJSDouble(theEnv)); - } - - JSValue eq(Environment theEnv, JSValue rV) { - JSValue lV = toPrimitive(theEnv, "Number"); - rV = rV.toPrimitive(theEnv, "Number"); - if ((lV instanceof JSString) && (rV instanceof JSString)) - return lV.eq(theEnv, rV); - else - return lV.toJSDouble(theEnv).eq(theEnv, rV.toJSDouble(theEnv)); - } - - JSValue ne(Environment theEnv, JSValue rV) { - JSValue lV = toPrimitive(theEnv, "Number"); - rV = rV.toPrimitive(theEnv, "Number"); - if ((lV instanceof JSString) && (rV instanceof JSString)) - return lV.ne(theEnv, rV); - else - return lV.toJSDouble(theEnv).ne(theEnv, rV.toJSDouble(theEnv)); - } - - JSValue plus(Environment theEnv) { - return toJSDouble(theEnv).plus(theEnv); - } - - JSValue minus(Environment theEnv) { - return toJSDouble(theEnv).minus(theEnv); - } - - JSValue twiddle(Environment theEnv) { - return toJSInteger(theEnv).twiddle(theEnv); - } - - JSValue bang(Environment theEnv) { - return toJSBoolean(theEnv).bang(theEnv); - } - - JSValue typeof(Environment theEnv) { - return unimplemented("typeof"); - } - - JSValue add(Environment theEnv, JSValue rV) { - JSValue lV = toPrimitive(theEnv, ""); - rV = rV.toPrimitive(theEnv, ""); - if ((lV instanceof JSString) || (rV instanceof JSString)) - return lV.add(theEnv, rV); - else - return lV.toJSDouble(theEnv).add(theEnv, rV); - } - - JSValue subtract(Environment theEnv, JSValue rV) { - return toJSDouble(theEnv).subtract(theEnv, rV.toJSDouble(theEnv)); - } - - JSValue multiply(Environment theEnv, JSValue rV) { - return toJSDouble(theEnv).multiply(theEnv, rV.toJSDouble(theEnv)); - } - - JSValue divide(Environment theEnv, JSValue rV) { - return toJSDouble(theEnv).divide(theEnv, rV.toJSDouble(theEnv)); - } - - JSValue remainder(Environment theEnv, JSValue rV) { - return toJSDouble(theEnv).remainder(theEnv, rV.toJSDouble(theEnv)); - } - - JSValue and(Environment theEnv, JSValue rV) { - return toJSInteger(theEnv).and(theEnv, rV.toJSInteger(theEnv)); - } - - JSValue or(Environment theEnv, JSValue rV) { - return toJSInteger(theEnv).or(theEnv, rV.toJSInteger(theEnv)); - } - - JSValue xor(Environment theEnv, JSValue rV) { - return toJSInteger(theEnv).xor(theEnv, rV.toJSInteger(theEnv)); - } - - JSValue shl(Environment theEnv, JSValue rV) { - return toJSInteger(theEnv).shl(theEnv, rV.toJSInteger(theEnv)); - } - - JSValue shr(Environment theEnv, JSValue rV) { - return toJSInteger(theEnv).shr(theEnv, rV.toJSInteger(theEnv)); - } - - JSValue ushl(Environment theEnv, JSValue rV) { - return toJSInteger(theEnv).ushl(theEnv, rV.toJSInteger(theEnv)); - } - - JSValue getProp(Environment theEnv, JSString id) { - return toJSObject(theEnv).getProp(theEnv, id); - } - - JSValue putProp(Environment theEnv, JSString id, JSValue rV) { - return toJSObject(theEnv).putProp(theEnv, id, rV); - } - - JSValue call(Environment theEnv, JSValue rV) { - throw new JSException(new JSString("[[call]] not implemented")); - } - - JSValue defaultValue(Environment theEnv, String hint) { -/* -When the [[DefaultValue]] method of O is called with hint String, the following steps are taken: -1. Call the [[Get]] method of object O with argument "toString". -2. If Result(1) is not an object, go to step 5. -3. Call the [[Call]] method of Result(1), with O as the this value and an empty argument list. -4. If Result(3) is a primitive value, return Result(3). -5. Call the [[Get]] method of object O with argument "valueOf". -6. If Result(5) is not an object, go to step 9. -7. Call the [[Call]] method of Result(5), with O as the this value and an empty argument list. -8. If Result(7) is a primitive value, return Result(7). -9. Generate a runtime error. -*/ - JSValue v = null; - if (hint.equals("String")) { - v = getProp(theEnv, new JSString("toString")); - if (v instanceof JSObject) { - // invoke 'v.Call' with 'this' as the JS this - } - else { - v = getProp(theEnv, new JSString("valueOf")); - if (v instanceof JSObject) { - } - else - throw new JSException(new JSString("No default value")); - } - } - else { // hint.equals("Number") -/* -When the [[DefaultValue]] method of O is called with hint Number, the following steps are taken: -1. Call the [[Get]] method of object O with argument "valueOf". -2. If Result(1) is not an object, go to step 5. -3. Call the [[Call]] method of Result(1), with O as the this value and an empty argument list. -4. If Result(3) is a primitive value, return Result(3). -5. Call the [[Get]] method of object O with argument "toString". -6. If Result(5) is not an object, go to step 9. -7. Call the [[Call]] method of Result(5), with O as the this value and an empty argument list. -8. If Result(7) is a primitive value, return Result(7). -9. Generate a runtime error. -*/ - - } - return null; - } - - JSValue toPrimitive(Environment theEnv, String hint) { - JSValue result = defaultValue(theEnv, hint); - if (result instanceof JSObject) - throw new JSException(new JSString("default value returned object")); - else - return result; - } - - - JSObject toJSObject(Environment theEnv) { unimplemented("toJSObjet"); return null; } - JSDouble toJSDouble(Environment theEnv) { unimplemented("toJSDouble"); return null; } - JSInteger toJSInteger(Environment theEnv) { unimplemented("toJSInteger"); return null; } - JSString toJSString(Environment theEnv) { unimplemented("toJSString"); return null; } - JSBoolean toJSBoolean(Environment theEnv) { unimplemented("toJSBoolean"); return null; } - -} \ No newline at end of file diff --git a/js/js2/java/NativeFunction.java b/js/js2/java/NativeFunction.java index 99761a252fb..e69de29bb2d 100644 --- a/js/js2/java/NativeFunction.java +++ b/js/js2/java/NativeFunction.java @@ -1,19 +0,0 @@ -class NativeFunction extends JSObject { - - NativeFunction(ControlNode aBody) - { - super("Function", null); - body = aBody; - } - - JSValue call(Environment theEnv, JSValue rV) - { - ControlNode c = body; - while (c != null) c = c.eval(theEnv); - - return theEnv.resultValue; - } - - ControlNode body; - -} \ No newline at end of file diff --git a/js/js2/java/NativeNumber.java b/js/js2/java/NativeNumber.java index e5874497089..e69de29bb2d 100644 --- a/js/js2/java/NativeNumber.java +++ b/js/js2/java/NativeNumber.java @@ -1,18 +0,0 @@ -class NativeNumber extends JSObject { - - NativeNumber(double p) { - super("Number", null); - d = p; - } - - JSValue defaultValue(Environment theEnv, String hint) { - if (hint.equals("String")) - return new JSString(Double.toString(d)); - else - return new JSDouble(d); - } - - double d; - - -} \ No newline at end of file diff --git a/js/js2/java/TryNode.java b/js/js2/java/TryNode.java index 18419e98162..e69de29bb2d 100644 --- a/js/js2/java/TryNode.java +++ b/js/js2/java/TryNode.java @@ -1,47 +0,0 @@ - -import java.util.Vector; - -class TryNode extends ControlNode { - - TryNode(ControlNode tryCode) - { - super(null); - tryBody = tryCode; - } - - void addFinally(ControlNode finallyCode) - { - finallyBody = finallyCode; - } - - void addCatchClause(ExpressionNode e, ControlNode c) - { - catchExpr.addElement(e); - catchCode.addElement(c); - } - - ControlNode eval(Environment theEnv) - { - try { - ControlNode c = tryBody; - while (c != null) c = c.eval(theEnv); - } - catch (JSException x) { - int count = catchExpr.size(); - for (int i = 0; i < count; i++) { - ExpressionNode e = (ExpressionNode)(catchExpr.elementAt(i)); - String id = ((JSObject)e).value; - theEnv.scope.contents.put(id, x.getValue()); // XXX YAARGH !!! - return (ControlNode)(catchCode.elementAt(i)); - } - } - return next; - } - - Vector catchExpr = new Vector(); - Vector catchCode = new Vector(); - - ControlNode tryBody; - ControlNode finallyBody; - -} \ No newline at end of file