예제 #1
0
  public Call semantic_analysis() {
    Call c = new Call(name, null, start, end);

    if (name.equals("scanf")) {
      Expr arg = args.arr.get(0);
      if (arg instanceof SingleIdExpr) {
        SingleIdExpr sarg = (SingleIdExpr) arg;
        STElem ste = get_sym_table_elem(sarg.name);
        ste.get_T(writer);
        writer.println("    READ  MEM(VR(0)@)");
      } else if (arg instanceof ArrayIdExpr) {
        ArrayIdExpr aarg = (ArrayIdExpr) arg;
        STElem ste = get_sym_table_elem(aarg.name);

        aarg.expr.semantic_analysis();
        block_idx++;
        writer.println("    MOVE  VR(0)@ VR(" + block_idx + ")");
        ste.get_T(writer);
        writer.println("    ADD   MEM(VR(0)@)@ VR(" + block_idx + ")@ VR(0)");
        writer.println("    READ  MEM(VR(0)@)");
        block_idx--;
      } else {
        semantic_error(this, "<scanf> should have an argument with Ident form.");
      }
      this.tn = TypeName.INT;
      return this;
    } else if (name.equals("printf")) {
      Expr _arg = args.arr.get(0).semantic_analysis();
      writer.println("    WRITE VR(0)@");

      args.arr.remove(0);
      args.add(_arg);
      this.tn = TypeName.INT;
      return this;
    } else {
      // function existance check
      FuncTable ft = get_fun_table(name);
      int param_size = 0;
      int i;
      if (ft == null) semantic_error(c, "Function " + name + " is not defined.");

      for (i = block_idx; i >= 1; i--) {
        push("VR(" + i + ")@");
      }

      if (args != null) {
        c.args = new ArgList();
        c.args.start = args.start;
        c.args.end = args.end;

        // argument size check
        int arg_size = args.arr.size();
        param_size = ft.arr.size();
        if (arg_size != param_size)
          semantic_error(
              c, "The number of arguments of function " + name + " should be " + param_size);

        // argument type check
        for (i = 0; i < param_size; i++) {
          Expr arg = args.arr.get(i);
          STElem param = ft.arr.get(i);

          Expr _arg = arg.semantic_analysis();
          if (param.is_array()) {
            // array type check
            if (param.typ.typ == TypeName.INT && _arg.tn != TypeName.INT_ARR)
              semantic_error(
                  _arg,
                  "Argument"
                      + (i + 1)
                      + " of the function "
                      + name
                      + " should have int array type.");
            if (param.typ.typ == TypeName.FLOAT && _arg.tn != TypeName.FLOAT_ARR)
              semantic_error(
                  _arg,
                  "Argument"
                      + (i + 1)
                      + " of the function "
                      + name
                      + " should have float array type.");
            push("VR(0)@");
          } else {
            if (param.typ.typ == TypeName.INT && _arg.tn != TypeName.INT) {
              if (_arg.tn == TypeName.FLOAT)
                semantic_warning(_arg, "This expression should have int type.");
              else semantic_error(_arg, "This expression should have int type.");
              _arg = new FloatToInt(_arg);
              writer.println("    F2I   VR(0)@ VR(0)");
            }
            if (param.typ.typ == TypeName.FLOAT && _arg.tn != TypeName.FLOAT) {
              if (_arg.tn == TypeName.INT)
                semantic_warning(_arg, "This expression should have int type.");
              else semantic_error(_arg, "This expression should have int type.");
              _arg = new IntToFloat(_arg);
              writer.println("    I2F   VR(0)@ VR(0)");
            }
            push("VR(0)@");
          }
          c.args.add(_arg);
        }
      }
      int ret_label_num = label_num++;
      push("_L" + ret_label_num);
      push("FP@");
      writer.println("    MOVE  SP@ FP");
      writer.println("    JMP   " + name);
      writer.println("LAB _L" + ret_label_num);
      writer.println("    SUB   SP@ " + (param_size + 1) + " SP");
      for (i = 1; i <= block_idx; i++) {
        pop("VR(" + i + ")");
      }
      c.tn = ft.typ.typ;
    }

    return c;
  }
예제 #2
0
 public void show_ast_c_ver() {
   writer.print(name + "(");
   if (args != null) args.show_ast_c_ver();
   writer.print(")");
 }