Example #1
0
  @Nullable
  /*package*/ SNode getTypeOf(final SNode node) {
    ModelAccess.assertLegalRead();
    if (node == null) return null;

    if (myTypeChecker.isGenerationMode()) {
      TypeCheckingContext context =
          myTypeChecker.hasPerformanceTracer()
              ? new TargetTypecheckingContext_Tracer(node, myTypeChecker)
              : new TargetTypecheckingContext(node, myTypeChecker);
      try {
        return context.getTypeOf_generationMode(node);
      } finally {
        context.dispose();
      }
    }
    // now we are not in generation mode

    final ITypeContextOwner contextOwner = myTypecheckingContextOwner.get();
    TypeCheckingContext context = acquireTypecheckingContext(node, contextOwner);
    if (context == null) {
      return TypesUtil.createRuntimeErrorType();
    }

    try {
      return context.getTypeOf(node, myTypeChecker);
    } finally {
      releaseTypecheckingContext(node, contextOwner);
    }
  }
  /**
   * Start one module after the other and try to compile the input file. Then generate the assembler
   * file and create this file for jasmin.
   */
  private static void parseCompile(String input, String fileName)
      throws ParserException, LexerException, IOException {
    String output; // Init output string
    StringReader reader =
        new StringReader(input); // Standard routine to start the parser, lexer, ...
    PushbackReader r = new PushbackReader(reader, 100);
    Lexer l = new Lexer(r);
    Parser parser = new Parser(l);
    Start start = parser.parse();

    //        ASTPrinter printer = new ASTPrinter();
    //        start.apply(printer);

    TypeChecker typeChecker = new TypeChecker(); // Starting TypeChecker
    start.apply(typeChecker);

    CodeGenerator codeGenerator = new CodeGenerator(typeChecker.getSymbolTable());
    copySymbolTable(
        typeChecker, codeGenerator); // To get all the identifiers copied with an index to CodeGen
    start.apply(codeGenerator);

    output = createOutput(codeGenerator, fileName);

    Writer wout =
        new BufferedWriter( // Write everything to the outputfile.j
            new OutputStreamWriter(new FileOutputStream(fileName + ".j"), "UTF8"));
    wout.append(output);
    wout.close();
  }
Example #3
0
 public TypeCheckingContext createTypeCheckingContext(SNode node) {
   ModelAccess.assertLegalRead();
   if (myTypeChecker.isGenerationMode()) {
     return new TargetTypecheckingContext(node, myTypeChecker);
   } else {
     return new IncrementalTypecheckingContext(node, myTypeChecker);
   }
 }
Example #4
0
  /** Type check the expression. */
  public Node typeCheck(TypeChecker tc) throws SemanticException {
    TypeSystem ts = tc.typeSystem();

    if (!ts.isCastValid(expr.type(), castType.type())) {
      throw new SemanticException(
          "Cannot cast the expression of type \""
              + expr.type()
              + "\" to type \""
              + castType.type()
              + "\".",
          position());
    }

    return type(castType.type());
  }
Example #5
0
  /**
   * Parse an expression
   *
   * @param token the initial token.
   * @return the root of the generated parse subtree.
   * @throws Exception if an error occurred.
   */
  private ICodeNode parseExpression(Token token) throws Exception {
    // Parse a simple expression and make the root of its tree
    // the root node.
    ICodeNode rootNode = parseSimpleExpression(token);
    TypeSpec resultType = rootNode != null ? rootNode.getTypeSpec() : Predefined.undefinedType;

    token = currentToken();
    TokenType tokenType = token.getType();

    // Look for a relational operator.
    if (REL_OPS.contains(tokenType)) {
      // Create a new operator node and adopt the current tree as its first child
      ICodeNodeType nodeType = REL_OPS_MAP.get(tokenType);
      ICodeNode opNode = ICodeFactory.createICodeNode(nodeType);
      opNode.addChild(rootNode);

      token = nextToken(); // consume the operator

      // Parse the second simple expression.
      // The operator node adopts the simple expression's tree as its second child.
      ICodeNode simExprNode = parseSimpleExpression(token);
      opNode.addChild(simExprNode);

      // The operator node becomes the new root node.
      rootNode = opNode;

      // Type check: The operands must be comparison compatible.
      TypeSpec simExprType =
          simExprNode != null ? simExprNode.getTypeSpec() : Predefined.undefinedType;
      if (TypeChecker.areComparisionCompatible(resultType, simExprType))
        resultType = Predefined.booleanType;
      else {
        errorHandler.flag(token, INCOMPATIBLE_TYPES, this);
        resultType = Predefined.undefinedType;
      }
    }

    if (rootNode != null) rootNode.setTypeSpec(resultType);
    return rootNode;
  }
Example #6
0
  public void typeCheckBody() throws XPathException {
    Expression exp = compiledFunction.getBody();
    Expression exp2 = exp;
    ExpressionVisitor visitor = makeExpressionVisitor();
    try {
      // We've already done the typecheck of each XPath expression, but it's worth doing again at
      // this
      // level because we have more information now.

      exp2 = visitor.typeCheck(exp, null);
      if (resultType != null) {
        RoleLocator role = new RoleLocator(RoleLocator.FUNCTION_RESULT, functionName, 0);
        role.setErrorCode("XTTE0780");
        exp2 = TypeChecker.staticTypeCheck(exp2, resultType, false, role, visitor);
      }
    } catch (XPathException err) {
      err.maybeSetLocation(this);
      compileError(err);
    }
    if (exp2 != exp) {
      compiledFunction.setBody(exp2);
    }
  }
Example #7
0
 private static boolean checkErrors(Program program, Level nonlinear) {
   boolean result = true;
   result = result && hasMainNode(program);
   result = result && TypeChecker.check(program);
   result = result && typesUnique(program);
   result = result && SubrangesNonempty.check(program);
   result = result && ArraysNonempty.check(program);
   result = result && constantsUnique(program);
   result = result && constantsConstant(program);
   result = result && nodesUnique(program);
   result = result && NodeDependencyChecker.check(program);
   result = result && variablesUnique(program);
   result = result && assignmentsSound(program);
   result = result && ConstantArrayAccessBounded.check(program);
   result = result && propertiesUnique(program);
   result = result && propertiesExist(program);
   result = result && propertiesBoolean(program);
   if (nonlinear == Level.ERROR) {
     result = result && LinearChecker.check(program, nonlinear);
   }
   result = result && DivisionChecker.check(program);
   return result;
 }
Example #8
0
  /** Type check the statement. */
  public Node typeCheck(TypeChecker tc) throws SemanticException {
    TypeSystem ts = tc.typeSystem();

    // Check that all initializers have the same type.
    // This should be enforced by the parser, but check again here,
    // just to be sure.
    Type t = null;

    for (Iterator i = inits.iterator(); i.hasNext(); ) {
      ForInit s = (ForInit) i.next();

      if (s instanceof LocalDecl) {
        LocalDecl d = (LocalDecl) s;
        Type dt = d.type().type();
        if (t == null) {
          t = dt;
        } else if (!t.equals(dt)) {
          throw new InternalCompilerError(
              "Local variable "
                  + "declarations in a for loop initializer must all "
                  + "be the same type, in this case "
                  + t
                  + ", not "
                  + dt
                  + ".",
              d.position());
        }
      }
    }

    if (cond != null && !ts.isImplicitCastValid(cond.type(), ts.Boolean())) {
      throw new SemanticException(
          "The condition of a for statement must have boolean type.", cond.position());
    }

    return this;
  }
 /**
  * Copy SymbolTable from the TypeChecker to the CodeGenerator and give it a new index (not
  * necessary to know the types any more - they are all correct!)
  */
 private static void copySymbolTable(TypeChecker typeChecker, CodeGenerator codeGenerator) {
   int i = typeChecker.getSymbolTable().size();
   for (String id : typeChecker.getSymbolTable().keySet())
     codeGenerator.getSymbolTable().put(id, i--);
 }
Example #10
0
 private int computeLabel(ASTree expr) throws CompileError {
   doTypeCheck(expr);
   expr = TypeChecker.stripPlusExpr(expr);
   if (expr instanceof IntConst) return (int) ((IntConst) expr).get();
   else throw new CompileError("bad case label");
 }
Example #11
0
 /** Type check the expression. */
 public Node typeCheck(TypeChecker tc) throws SemanticException {
   return type(tc.typeSystem().Boolean());
 }
Example #12
0
  /**
   * Compile: this registers the template with the rule manager, and ensures space is available for
   * local variables
   */
  public Expression compile(Executable exec) throws XPathException {

    Expression block = compileSequenceConstructor(exec, iterateAxis(Axis.CHILD), true);
    if (block == null) {
      block = Literal.makeEmptySequence();
    }
    compiledTemplate.setMatchPattern(match);
    compiledTemplate.setBody(block);
    compiledTemplate.setStackFrameMap(stackFrameMap);
    compiledTemplate.setExecutable(getExecutable());
    compiledTemplate.setSystemId(getSystemId());
    compiledTemplate.setLineNumber(getLineNumber());
    compiledTemplate.setHasRequiredParams(hasRequiredParams);
    compiledTemplate.setRequiredType(requiredType);

    Expression exp = null;
    try {
      exp = makeExpressionVisitor().simplify(block);
    } catch (XPathException e) {
      compileError(e);
    }

    try {
      if (requiredType != null) {
        RoleLocator role = new RoleLocator(RoleLocator.TEMPLATE_RESULT, diagnosticId, 0);
        // role.setSourceLocator(new ExpressionLocation(this));
        role.setErrorCode("XTTE0505");
        exp = TypeChecker.staticTypeCheck(exp, requiredType, false, role, makeExpressionVisitor());
      }
    } catch (XPathException err) {
      compileError(err);
    }

    compiledTemplate.setBody(exp);
    compiledTemplate.init(getObjectName(), getPrecedence(), getMinImportPrecedence());

    if (getConfiguration().isCompileWithTracing()) {
      TraceWrapper trace = new TraceInstruction(exp, this);
      trace.setLocationId(allocateLocationId(getSystemId(), getLineNumber()));
      trace.setContainer(compiledTemplate);
      exp = trace;
      compiledTemplate.setBody(exp);
    }

    ItemType contextItemType = Type.ITEM_TYPE;
    if (getObjectName() == null) {
      // the template can't be called by name, so the context item must match the match pattern
      contextItemType = match.getNodeTest();
    }

    ExpressionVisitor visitor = makeExpressionVisitor();
    try {
      // We've already done the typecheck of each XPath expression, but it's worth doing again at
      // this
      // level because we have more information now.
      Expression exp2 = visitor.typeCheck(exp, contextItemType);
      exp2 = visitor.optimize(exp2, contextItemType);
      if (exp != exp2) {
        compiledTemplate.setBody(exp2);
        exp = exp2;
      }
    } catch (XPathException e) {
      compileError(e);
    }

    // Try to extract new global variables from the body of the function
    //        ExpressionPresenter presenter = ExpressionPresenter.make(getConfiguration());
    //        exp.explain(presenter);
    //        presenter.close();
    if (!getConfiguration().isCompileWithTracing()) {
      Expression exp2 = getConfiguration().getOptimizer().promoteExpressionsToGlobal(exp, visitor);
      if (exp != exp2) {
        compiledTemplate.setBody(exp2);
        exp = exp2;
      }
    }

    allocateSlots(exp);
    if (match != null) {
      RuleManager mgr = getPrincipalStylesheet().getRuleManager();
      for (int i = 0; i < modeNames.length; i++) {
        StructuredQName nc = modeNames[i];
        Mode mode = mgr.getMode(nc, true);
        if (prioritySpecified) {
          mgr.setHandler(match, compiledTemplate, mode, getPrecedence(), priority);
        } else {
          mgr.setHandler(match, compiledTemplate, mode, getPrecedence());
        }
      }

      allocatePatternSlots(match, getSlotManager());
    }

    if (isExplaining()) {
      System.err.println(
          "Optimized expression tree for template at line "
              + getLineNumber()
              + " in "
              + getSystemId()
              + ':');
      exp.explain(System.err);
    }

    return null;
  }
Example #13
0
  /**
   * Parse a factor.
   *
   * @param token the initial token.
   * @return the root of the generated parse subtree.
   * @throws Exception if an error occurred.
   */
  private ICodeNode parseFactor(Token token) throws Exception {
    TokenType tokenType = token.getType();
    ICodeNode rootNode = null;

    switch ((PascalTokenType) tokenType) {
      case IDENTIFIER:
        {
          return parseIdentifier(token);
        }

      case INTEGER:
        {
          // Create an INTEGER_CONSTANT node as the root node
          rootNode = ICodeFactory.createICodeNode(INTEGER_CONSTANT);
          rootNode.setAttribute(VALUE, token.getValue());

          token = nextToken(); // consume the number
          rootNode.setTypeSpec(Predefined.integerType);
          break;
        }

      case REAL:
        {
          // Create an REAL_CONSTANT node as the root node.
          rootNode = ICodeFactory.createICodeNode(REAL_CONSTANT);
          rootNode.setAttribute(VALUE, token.getValue());

          token = nextToken(); // consume the number

          rootNode.setTypeSpec(Predefined.realType);
          break;
        }

      case STRING:
        {
          String value = (String) token.getValue();

          // Create a STRING_CONSTANT node as the root node.
          rootNode = ICodeFactory.createICodeNode(STRING_CONSTANT);
          rootNode.setAttribute(VALUE, value);

          TypeSpec resultType =
              value.length() == 1 ? Predefined.charType : TypeFactory.createStringType(value);

          token = nextToken(); // consume the string
          rootNode.setTypeSpec(resultType);
          break;
        }

      case NOT:
        {
          token = nextToken(); // consume the NOT

          // Create a NOT node as the root node.
          rootNode = ICodeFactory.createICodeNode(ICodeNodeTypeImpl.NOT);

          // Parse the factor. The NOT node adopts the factor node as its child.
          ICodeNode factorNode = parseFactor(token);
          rootNode.addChild(factorNode);

          // Type check: the factor must be boolean.
          TypeSpec factorType =
              factorNode != null ? factorNode.getTypeSpec() : Predefined.undefinedType;
          if (!TypeChecker.isBoolean(factorType))
            errorHandler.flag(token, INCOMPATIBLE_TYPES, this);
          rootNode.setTypeSpec(Predefined.booleanType);
          break;
        }

      case LEFT_PAREN:
        {
          token = nextToken(); // consume the (

          // Parse an expression and make its node the root node.
          rootNode = parseExpression(token);
          TypeSpec resultType =
              rootNode != null ? rootNode.getTypeSpec() : Predefined.undefinedType;

          // Look for the matching ) token.
          token = currentToken();
          if (token.getType() == RIGHT_PAREN) token = nextToken(); // consume the )
          else errorHandler.flag(token, MISSING_RIGHT_PAREN, this);
          rootNode.setTypeSpec(resultType);
          break;
        }

      default:
        {
          errorHandler.flag(token, UNEXPECTED_TOKEN, this);
          break;
        }
    }
    return rootNode;
  }
Example #14
0
  /**
   * Parse a term.
   *
   * @param token the initial token.
   * @return the root of the generated parse subtree.
   * @throws Exception if an error occurred.
   */
  private ICodeNode parseTerm(Token token) throws Exception {
    // Parse a factor and makes its node the root node.
    ICodeNode rootNode = parseFactor(token);
    TypeSpec resultType = rootNode != null ? rootNode.getTypeSpec() : Predefined.undefinedType;

    token = currentToken();
    TokenType tokenType = token.getType();

    // Loop over multiplicative operators.
    while (MULT_OPS.contains(tokenType)) {
      TokenType operator = tokenType;

      // Create a new operator node and adopt the current tree as its first child.
      ICodeNodeType nodeType = MULT_OPS_OPS_MAP.get(operator);
      ICodeNode opNode = ICodeFactory.createICodeNode(nodeType);
      opNode.addChild(rootNode);

      token = nextToken(); // consume the operator

      // Parse another factor.
      // The operator node adopts the term's tree as its secomd child.
      ICodeNode factorNode = parseFactor(token);
      opNode.addChild(factorNode);
      TypeSpec factorType =
          factorNode != null ? factorNode.getTypeSpec() : Predefined.undefinedType;
      // The operator node becomes the new root node.
      rootNode = opNode;

      // Determine the result type.
      switch ((PascalTokenType) operator) {
        case STAR:
          {
            // Both operands integer ==> integer result.
            if (TypeChecker.areBothInteger(resultType, factorType)) {
              resultType = Predefined.integerType;
            }

            // Both real operands or one real and one integer operand
            // ==> real result.
            else if (TypeChecker.isAtLeastOneReal(resultType, factorType)) {
              resultType = Predefined.realType;
            } else {
              errorHandler.flag(token, INCOMPATIBLE_TYPES, this);
            }

            break;
          }

        case SLASH:
          {
            // All integer and real operand combinations
            // ==> real result.
            if (TypeChecker.areBothInteger(resultType, factorType)
                || TypeChecker.isAtLeastOneReal(resultType, factorType)) {
              resultType = Predefined.realType;
            } else {
              errorHandler.flag(token, INCOMPATIBLE_TYPES, this);
            }

            break;
          }

        case DIV:
        case MOD:
          {
            // Both operands integer ==> integer result.
            if (TypeChecker.areBothInteger(resultType, factorType)) {
              resultType = Predefined.integerType;
            } else {
              errorHandler.flag(token, INCOMPATIBLE_TYPES, this);
            }

            break;
          }

        case AND:
          {
            // Both operands boolean ==> boolean result.
            if (TypeChecker.areBothBoolean(resultType, factorType)) {
              resultType = Predefined.booleanType;
            } else {
              errorHandler.flag(token, INCOMPATIBLE_TYPES, this);
            }

            break;
          }
      }

      // The operator node becomes the new root node.
      rootNode.setTypeSpec(resultType);

      token = currentToken();
      tokenType = token.getType();
    }
    return rootNode;
  }
Example #15
0
  /**
   * Parse a simple expression.
   *
   * @param token the initial token.
   * @return the root of the generated parse subtree.
   * @throws Exception if an error occurred.
   */
  private ICodeNode parseSimpleExpression(Token token) throws Exception {
    Token signToken = null;
    TokenType signType = null; // type of leading sign (if any)

    // Look for a leading + or - sign
    TokenType tokenType = token.getType();
    if ((tokenType == PLUS) || (tokenType == MINUS)) {
      signType = tokenType;
      signToken = token;
      token = nextToken(); // consume the + or -
    }

    // Parse a term and make the root of its tree the root node.
    ICodeNode rootNode = parseTerm(token);
    TypeSpec resultType = rootNode != null ? rootNode.getTypeSpec() : Predefined.undefinedType;

    // Type check: Leading sign.
    if ((signType != null) && (!TypeChecker.isIntegerOrReal(resultType)))
      errorHandler.flag(signToken, INCOMPATIBLE_TYPES, this);

    // Was there a leading - sign?
    if (signType == MINUS) {
      // Create a NEGATE node and adopt the current tree as its child.
      // The NEGATE node becomes the new root node.
      ICodeNode negateNode = ICodeFactory.createICodeNode(NEGATE);
      negateNode.addChild(rootNode);
      negateNode.setTypeSpec(rootNode.getTypeSpec());
      rootNode = negateNode;
    }

    token = currentToken();
    tokenType = token.getType();

    // Loop over additive operators.
    while (ADD_OPS.contains(tokenType)) {
      TokenType operator = tokenType;

      // Create a new operator node and adopt the current tree as its first child.
      ICodeNodeType nodeType = ADD_OPS_OPS_MAP.get(operator);
      ICodeNode opNode = ICodeFactory.createICodeNode(nodeType);
      opNode.addChild(rootNode);

      token = nextToken(); // consume the operator

      // Parse another term.
      // The operator node adopts the term's tree as its second child.
      ICodeNode termNode = parseTerm(token);
      opNode.addChild(termNode);
      TypeSpec termType = termNode != null ? termNode.getTypeSpec() : Predefined.undefinedType;

      // The operator node becomes the new root node.
      rootNode = opNode;

      switch ((PascalTokenType) operator) {
        case PLUS:
        case MINUS:
          {
            // Both operands integer => integer result.
            if (TypeChecker.areBothInteger(resultType, termType))
              resultType = Predefined.integerType;

            // Both real operands or one real and one integer operand => real result.
            else if (TypeChecker.isAtLeastOneReal(resultType, termType))
              resultType = Predefined.realType;
            else errorHandler.flag(token, INCOMPATIBLE_TYPES, this);
            break;
          }

        case OR:
          {
            // Both operands boolean ==> boolean result.
            if (TypeChecker.areBothBoolean(resultType, termType))
              resultType = Predefined.booleanType;
            else errorHandler.flag(token, INCOMPATIBLE_TYPES, this);
            break;
          }
      }

      rootNode.setTypeSpec(resultType);
      token = currentToken();
      tokenType = token.getType();
    }
    return rootNode;
  }