Beispiel #1
0
 /**
  * Create a new parser. (This is mainly for internal use in this class.)
  *
  * @param parent if the parent is non-null, then this parser inherits any symbols that have been
  *     added to the parent parser. Symbols that are added to this parser do not affect the parent,
  *     but will hide symbols in the parent that have the same name making them unavailable for use
  *     by this parser.
  */
 public Parser(Parser parent) {
   if (parent != null) symbolTable = new SymbolTable(parent.symbolTable);
   else {
     symbolTable = new SymbolTable();
     add(PI);
     add(E);
     add(I);
     StandardFunction[] functions = StandardFunction.getFunctions();
     for (StandardFunction f : functions) symbolTable.put(f.getName().toLowerCase(), f);
   }
 }
 /** Non-standard constructor to create an internal call on key() with a known key fingerprint */
 public static KeyFn internalKeyCall(
     NamePool pool, int fingerprint, String name, Expression value, Expression doc) {
   KeyFn k = new KeyFn();
   Expression[] arguments = {new StringValue(name), value, doc};
   k.argument = arguments;
   k.keyFingerprint = fingerprint;
   k.checked = true;
   k.internal = true;
   k.setDetails(StandardFunction.getFunction("key", 3));
   k.setFunctionNameCode(pool.allocate("fn", NamespaceConstant.FN, "key"));
   k.adoptChildExpression(value);
   k.adoptChildExpression(doc);
   return k;
 }
Beispiel #3
0
 private Type parseNumericalPrimary(Context cntx) {
   Type type;
   Token tok = cntx.next();
   Token openingParen;
   switch (tok) {
     case NUMBER:
       cntx.bldr.addRealConstant(cntx.number);
       return Type.REAL;
     case VARIABLE:
       cntx.bldr.addVariableRef((Variable) cntx.symbol);
       return Type.REAL;
     case ARGUMENT:
       cntx.bldr.addArgumentReference(((Argument) cntx.symbol).argnum);
       return Type.REAL;
     case COMPLEX_VARIABLE:
       cntx.bldr.addComplexVariableRef((ComplexVariable) cntx.symbol);
       return Type.COMPLEX;
     case COMPLEX_ARGUMENT:
       cntx.bldr.addArgumentReference(((ComplexArgument) cntx.symbol).argnum);
       return Type.COMPLEX;
     case FUNCTION:
     case COMPLEX_FUNCTION:
     case STANDARD_FUNCTION:
     case FUNCTION_COMPLEX_TO_REAL:
       Token funcTok = tok;
       Object symbol = cntx.symbol;
       String funcName = cntx.tokstr;
       openingParen = cntx.next();
       if (openingParen != Token.LEFT_PAREN
           && openingParen != Token.LEFT_BRACE
           && openingParen != Token.LEFT_BRACKET)
         error(cntx, "vmm.parser.FunctionRequiresParen", funcName);
       int argCount = 0;
       int expectedArgs =
           funcTok == Token.FUNCTION
               ? ((Function) symbol).getArity()
               : funcTok == Token.COMPLEX_FUNCTION
                   ? ((ComplexFunction) symbol).getArity()
                   : funcTok == Token.STANDARD_FUNCTION ? 1 : 2;
       Type argType = null;
       while (true) {
         tok = cntx.peek();
         if (tok == Token.RIGHT_PAREN || tok == Token.RIGHT_BRACE || tok == Token.RIGHT_BRACKET)
           break;
         argCount++;
         if (argCount > expectedArgs) error(cntx, "vmm.parser.TooManyArguments", funcName);
         argType = parseBExpr(cntx);
         if (funcTok == Token.FUNCTION || funcTok == Token.FUNCTION_COMPLEX_TO_REAL) {
           if (argType != Type.REAL) error(cntx, "vmm.parser.NeedRealArgument", funcName);
         } else if (funcTok == Token.COMPLEX_FUNCTION) {
           if (argType == Type.BOOLEAN) error(cntx, "vmm.parser.NeedComplexArgument", funcName);
           if (argType == Type.REAL) cntx.bldr.addStackOp(StackOp.REAL_TO_COMPLEX);
         } else if (funcTok == Token.STANDARD_FUNCTION) {
           StandardFunction f = (StandardFunction) symbol;
           if (argType == Type.COMPLEX) {
             if (f.getComplexArgOp() == null) error(cntx, "vmm.parser.NeedRealArgument", funcName);
           } else if (argType == Type.REAL) {
             if (f.getRealArgOp() == null
                 || (cntx.complexOnly && needRealToComplex.contains(f.getRealArgOp()))) {
               cntx.bldr.addStackOp(StackOp.REAL_TO_COMPLEX);
               argType = Type.COMPLEX;
             }
           } else { // argType is boolean
             if (f.getRealArgOp() == null
                 || (cntx.complexOnly && needRealToComplex.contains(f.getRealArgOp())))
               error(cntx, "vmm.parser.NeedComplexArgument", funcName);
             else error(cntx, "vmm.parser.NeedRealArgument", funcName);
           }
         }
         tok = cntx.peek();
         if (tok != Token.COMMA) break;
         cntx.next();
       }
       tok = cntx.next();
       if (argCount < expectedArgs) error(cntx, "vmm.parser.NotEnoughArguments", funcName);
       if (openingParen == Token.LEFT_PAREN && tok != Token.RIGHT_PAREN)
         error(cntx, "vmm.parser.MissingCloseOfArgumentList", ")");
       if (openingParen == Token.LEFT_BRACE && tok != Token.RIGHT_BRACE)
         error(cntx, "vmm.parser.MissingCloseOfArgumentList", "}");
       if (openingParen == Token.LEFT_BRACKET && tok != Token.RIGHT_BRACKET)
         error(cntx, "vmm.parser.MissingCloseOfArgumentList", "]");
       if (funcTok == Token.FUNCTION) {
         cntx.bldr.addFunctionRef(((Function) symbol).getProgFunction());
         return Type.REAL;
       } else if (funcTok == Token.COMPLEX_FUNCTION) {
         cntx.bldr.addFunctionRef(((ComplexFunction) symbol).getProgFunction());
         return Type.COMPLEX;
       } else if (funcTok == Token.FUNCTION_COMPLEX_TO_REAL) return Type.COMPLEX;
       else {
         StandardFunction f = (StandardFunction) symbol;
         cntx.bldr.addStackOp(argType == Type.COMPLEX ? f.getComplexArgOp() : f.getRealArgOp());
         return argType == Type.COMPLEX
             ? f.getReturnTypeForComplexArg()
             : f.getReturnTypeForRealArg();
       }
     case LEFT_PAREN:
       type = parseBExpr(cntx);
       tok = cntx.next();
       if (tok == Token.EOS) error(cntx, "vmm.parser.MissingRightGroupThingAtEOS", ")", "(");
       if (tok != Token.RIGHT_PAREN)
         error(cntx, "vmm.parser.MissingRightGroupThing", ")", "(", cntx.tokstr);
       return type;
     case LEFT_BRACE:
       type = parseBExpr(cntx);
       tok = cntx.next();
       if (tok == Token.EOS) error(cntx, "vmm.parser.MissingRightGroupThingAtEOS", "]", "[");
       if (tok != Token.RIGHT_BRACE)
         error(cntx, "vmm.parser.MissingRightGroupThing", "]", "[", cntx.tokstr);
       return type;
     case LEFT_BRACKET:
       type = parseBExpr(cntx);
       tok = cntx.next();
       if (tok == Token.EOS) error(cntx, "vmm.parser.MissingRightGroupThingAtEOS", "}", "{");
       if (tok != Token.RIGHT_PAREN)
         error(cntx, "vmm.parser.MissingRightGroupThing", "}", "{", cntx.tokstr);
       return type;
     case RIGHT_PAREN:
       error(cntx, "vmm.parser.ExtraRightGroupThing", ")", "(");
       return null;
     case RIGHT_BRACE:
       error(cntx, "vmm.parser.ExtraRightGroupThing", "}", "{");
       return null;
     case RIGHT_BRACKET:
       error(cntx, "vmm.parser.ExtraRightGroupThing", "]", "[");
       return null;
     case UNKNOWN_CHAR:
       error(cntx, "vmm.parser.UnknownChar", cntx.tokstr);
       return null;
     case UNKNOWN_WORD:
       error(cntx, "vmm.parser.UndefinedWord", cntx.tokstr);
       return null;
     case ILLEGAL_NUMBER:
       error(cntx, "vmm.parser.IllegalNumber", cntx.tokstr);
       return null;
     case EOS:
       error(cntx, "vmm.parser.IncompleteExpression");
     default:
       error(cntx, "vmm.parser.UnexcpectedToken", cntx.tokstr);
       return null;
   }
 }