public void emit_get_class_object(Codegen c, CodeGeneratorState s)
     throws PlcException, IOException {
   if (is_void() && !is_container()) // c.emit_summon_null();
   throw new PlcException("PhantomType", "asked to emit void class object"); // Why not, btw?
   else if (is_int()) c.emitSummonByName(".internal.int");
   else if (is_long()) c.emitSummonByName(".internal.long");
   else if (is_float()) c.emitSummonByName(".internal.float");
   else if (is_double()) c.emitSummonByName(".internal.double");
   else if (is_string()) c.emitSummonByName(".internal.string");
   else if (is_container()) {
     if (_container_class != null) c.emitSummonByName(_container_class.getName());
     else if (_container_class_expression != null) _container_class_expression.generate_code(c, s);
     else c.emitSummonByName(".internal.container.array");
   } else if (_class != null) c.emitSummonByName(_class.getName());
   else if (_class_expression != null) _class_expression.generate_code(c, s);
   else throw new PlcException("emit_get_class_object", "can't get class object");
 }
示例#2
0
  public void generate_code(CodeGeneratorState s) throws PlcException, IOException {
    if (code == null) {
      c.emitRet(); // empty function code
      return;
    }

    // ------------------------------------------
    // traverse tree to allocate automatic vars?
    // ------------------------------------------
    int n_auto_vars = svars.getUsedSlots();
    int n_int_auto_vars = isvars.getUsedSlots();
    // ------------------------------------------

    // ------------------------------------------
    // generate prologue code here
    // ------------------------------------------

    // check number of args
    int n_args = args_def.size();
    String good_args_label = c.getLabel();

    c.emitIConst_32bit(n_args);
    c.emitISubLU();
    c.emitJz(good_args_label);

    // wrong count - throw string
    // BUG! Need less consuming way of reporting this. Maybe by
    // calling class object Method? Or by summoning something?
    c.emitString("arg count: " + name + " in " + s.get_class().getName());
    c.emitThrow();

    c.markLabel(good_args_label);

    if (requestDebug) c.emitDebug((byte) 0x1, "Enabled debug");

    // push nulls to reserve stack space for autovars
    // BUG! We can execute vars initialization code here, can we?
    // We can if code does not depend on auto vars itself, or depends only on
    // previous ones.
    // TODO: BUG! autovars in arguments are already on stack, we don't have to reserve space
    for (int i = n_auto_vars; i > 0; i--) c.emitPushNull();

    // TODO introduce instruction to reserve o+i space in one step
    // Reserve integer stack place for int vars
    for (int i = n_int_auto_vars; i > 0; i--) c.emitIConst_0();

    // ------------------------------------------

    // ------------------------------------------
    // generate main code by descending the tree
    // ------------------------------------------
    code.generate_code(c, s);
    // ------------------------------------------

    // ------------------------------------------
    // generate epilogue code here
    // ------------------------------------------
    if (requestDebug) c.emitDebug((byte) 0x2, "Disabled debug");
    c.emitRet(); // catch the fall-out
    // ------------------------------------------

  }
 protected void generate_my_code(Codegen c, CodeGeneratorState s)
     throws IOException, PlcException {
   c.emit_inot();
 }