Exemplo n.º 1
0
void c_mod() {
    CHECK_TYPES(sp - 1, T_NUMBER, 1, F_MOD);
    CHECK_TYPES(sp, T_NUMBER, 2, F_MOD);
    if ((sp--)->u.number == 0)
	error("Modulus by zero.\n");
    sp->u.number %= (sp+1)->u.number;
}
void zu::postfix_writer::do_zuidentifier_node(zu::zuidentifier_node * const node, int lvl) {
	  CHECK_TYPES(_compiler, _symtab, node);
          node->accept(this,lvl);
          CHECK_TYPES(_compiler, _symtab, node);
  // simplified generation: all variables are global
          _pf.ADDR(node->id());
}
Exemplo n.º 3
0
void c_foreach P3(int, flags, int, idx1, int, idx2) {
    IF_DEBUG(stack_in_use_as_temporary++);
    
    if (flags & 4) {
	CHECK_TYPES(sp, T_MAPPING, 2, F_FOREACH);
	
	push_refed_array(mapping_indices(sp->u.map));
	(++sp)->type = T_NUMBER;
	sp->u.lvalue = (sp-1)->u.arr->item;
	sp->subtype = (sp-1)->u.arr->size;
		    
	(++sp)->type = T_LVALUE;
	if (flags & 2)
	    sp->u.lvalue = &current_object->variables[idx1 + variable_index_offset];
	else
	    sp->u.lvalue = fp + idx1;
    } else 
    if (sp->type == T_STRING) {
	(++sp)->type = T_NUMBER;
	sp->u.lvalue_byte = (unsigned char *)((sp-1)->u.string);
	sp->subtype = SVALUE_STRLEN(sp - 1);
    } else {
	CHECK_TYPES(sp, T_ARRAY, 2, F_FOREACH);

	(++sp)->type = T_NUMBER;
	sp->u.lvalue = (sp-1)->u.arr->item;
	sp->subtype = (sp-1)->u.arr->size;
    }

    (++sp)->type = T_LVALUE;
    if (flags & 1)
	sp->u.lvalue = &current_object->variables[idx2 + variable_index_offset];
    else
	sp->u.lvalue = fp + idx2;
}
Exemplo n.º 4
0
void c_foreach(int  flags, int  idx1, int  idx2) {
    IF_DEBUG(stack_in_use_as_temporary++);
    
    if (flags & FOREACH_MAPPING) {
	CHECK_TYPES(sp, T_MAPPING, 2, F_FOREACH);
	
	push_refed_array(mapping_indices(sp->u.map));

	STACK_INC;
	sp->type = T_NUMBER;
	sp->u.lvalue = (sp-1)->u.arr->item;
	sp->subtype = (sp-1)->u.arr->size;
		    
	STACK_INC;
	sp->type = T_LVALUE;
	if (flags & FOREACH_LEFT_GLOBAL) {
	    sp->u.lvalue = &current_object->variables[idx1 + variable_index_offset];
	} else {
	    sp->u.lvalue = fp + idx1;
	}
    } else 
    if (sp->type == T_STRING) {
	STACK_INC;
	sp->type = T_NUMBER;
	sp->u.lvalue_byte = (unsigned char *)((sp-1)->u.string);
	sp->subtype = SVALUE_STRLEN(sp - 1);
    } else {
	CHECK_TYPES(sp, T_ARRAY, 2, F_FOREACH);

	STACK_INC;
	sp->type = T_NUMBER;
	sp->u.lvalue = (sp-1)->u.arr->item;
	sp->subtype = (sp-1)->u.arr->size;
    }

    if (flags & FOREACH_RIGHT_GLOBAL) {
	STACK_INC;
	sp->type = T_LVALUE;
	sp->u.lvalue = &current_object->variables[idx2 + variable_index_offset];
    } else if (flags & FOREACH_REF) {
	ref_t *ref = make_ref();
	svalue_t *loc = fp + idx2;

	/* foreach guarantees our target remains valid */
	ref->lvalue = 0;
	ref->sv.type = T_NUMBER;
	STACK_INC;
	sp->type = T_REF;
	sp->u.ref = ref;
	DEBUG_CHECK(loc->type != T_NUMBER && loc->type != T_REF, "Somehow a reference in foreach acquired a value before coming into scope");
	loc->type = T_REF;
	loc->u.ref = ref;
	ref->ref++;
    } else {
	STACK_INC;
	sp->type = T_LVALUE;
	sp->u.lvalue = fp + idx2;
    }
}
Exemplo n.º 5
0
void c_parse_command(int  num_arg) {
    svalue_t *arg;
    svalue_t *fp;
    int i;

    /*
     * type checking on first three required parameters to parse_command()
     */
    arg = sp - 2;
    CHECK_TYPES(&arg[0], T_STRING, 1, F_PARSE_COMMAND);
    CHECK_TYPES(&arg[1], T_OBJECT | T_ARRAY, 2, F_PARSE_COMMAND);
    CHECK_TYPES(&arg[2], T_STRING, 3, F_PARSE_COMMAND);

    /*
     * allocate stack frame for rvalues and return value (number of matches);
     * perform some stack manipulation;
     */
    fp = sp;
    CHECK_STACK_OVERFLOW(num_arg + 1);
    sp += num_arg + 1;
    arg = sp;
    *(arg--) = *(fp--);		/* move pattern to top of stack */
    *(arg--) = *(fp--);		/* move source object or array to just below 
				   the pattern */
    *(arg) = *(fp);		/* move source string just below the object */
    fp->type = T_NUMBER;

    /*
     * prep area for rvalues
     */
    for (i = 1; i <= num_arg; i++)
	fp[i].type = T_INVALID;

    /*
     * do it...
     */
    i = parse(arg[0].u.string, &arg[1], arg[2].u.string, &fp[1], num_arg);

    /*
     * remove mandatory parameters
     */
    pop_3_elems();

    /*
     * save return value on stack
     */
    fp->u.number = i;
}
Exemplo n.º 6
0
void pwn::postfix_writer::do_simple_lvalue_node(pwn::simple_lvalue_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);

  std::string id = fix_id(node->value());
  std::shared_ptr<pwn::symbol> symbol = _symtab.find(id); 
  
  if ( ! _current_function) {
    // global context
    if ( ! symbol->is_var()) {
      throw "Error: assigning a value to a function";
    }
    
    _pf.ADDR(id);
  } else {
    // local context
    bool is_return_symbol = ( ! symbol->is_var()) // the symbol is a function
                         && (_current_function->name() == symbol->name()) // the symbol has the same name as the current function
                         && ( ! is_void(_current_function->type())); // the function doesnt "return" void
                         
    if (is_return_symbol) {
      if (is_double(_current_function->type())) {
        _pf.LOCAL(-8); // double @ -8
      } else {
        _pf.LOCAL(-4); // int, string, pointer @ -4
      }
    } else if (symbol->is_var() && symbol->name() != _current_function->name()) {
      _pf.LOCAL(symbol->offset());
    } else {
      throw "Error: invalid left value";
    }
  }

}
Exemplo n.º 7
0
void pwn::postfix_writer::do_add_node(cdk::add_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);
  
  if (is_pointer(node->type())) {
    if (is_int(node->left()->type())) {
      node->right()->accept(this, lvl + 1); // load the pointer
      node->left()->accept(this, lvl + 1); // load the shift
    } else {
      node->left()->accept(this, lvl + 1); // load the pointer
      node->right()->accept(this, lvl + 1); // load the shift
    } 
    
    _pf.INT(4); // pointer size
    _pf.MUL(); // pointer arithmetics shift calculation
    _pf.ADD();
      
    return;
  }
  
  node->left()->accept(this, lvl);
  if (is_double(node->type()) && is_int(node->left()->type())) {
    _pf.I2D();
  }
  
  node->right()->accept(this, lvl);
  if (is_double(node->type()) && is_int(node->right()->type())) {
    _pf.I2D();
  }
  
  if (is_int(node->type())) {
    _pf.ADD();    
  } else if (is_double(node->type())) {
    _pf.DADD();
  }
}
void zu::postfix_writer::do_var_declaration_node(zu::var_declaration_node * const node, int lvl){
    CHECK_TYPES(_compiler, _symtab, node);
    std::string identifier = *(node->identifier()->identifier());
    std::shared_ptr<zu::symbol> symbol = _symtab.find(identifier);
    
    if(node->ext()){
        _pf.EXTERN(identifier);
    }else if(!_am_I_in_function){
        if(node->visibility()){
            _pf.GLOBAL(identifier, _pf.OBJ());
            symbol->is_global(true);
        }
        _pf.BSS();
        _pf.ALIGN();
        _pf.LABEL(identifier);
        _pf.BYTE(node->type()->size());
        _pf.TEXT();
        _pf.ALIGN();
        
    }else{
        if(_is_arg){
            symbol->offset(_arg_offset);
            _arg_offset += symbol->type()->size();
            symbol->is_global(false);
        }else {
            symbol->offset(-_max_offset);
            _max_offset -= symbol->type()->size();
            symbol->is_global(false);
        }
    }
   
    
    
}
Exemplo n.º 9
0
void zu::postfix_writer::do_div_node(cdk::div_node * const node, int lvl) {
    //debug(node, lvl);
  CHECK_TYPES(_compiler, _symtab, node);
  node->left()->accept(this, lvl+2);
  node->right()->accept(this, lvl+2);
  _pf.DIV();
}
Exemplo n.º 10
0
void zu::postfix_writer::do_functioninvocation_node(zu::functioninvocation_node * const node, int lvl) {
    CHECK_TYPES(_compiler,_symtab,node);
    int remove_bits = 0;
    if(node->args() != NULL){
        for(size_t i = 0; i < node->args()->size(); i++){
            node->args()->node(i)->accept(this, lvl+2);
            remove_bits +=((cdk::expression_node *) node->args()->node(i))->type()->size();
        }
    }
    
    _pf.CALL(node->identifier()->name());
    _pf.TRASH(remove_bits);
    
    //find symbol of function to call
    std::shared_ptr<zu::symbol> sym = _symtab.find(node->identifier()->name());
    if(sym == nullptr)
        std::cerr << "ERROR: function '"<< node->identifier()->name() <<"' not found " << std::endl;
    
    if(sym->type()->name() == basic_type::TYPE_POINTER ||
        sym->type()->name() == basic_type::TYPE_INT ||
        sym->type()->name() == basic_type::TYPE_STRING)
        _pf.PUSH();
    else
        _pf.DPUSH();
  
}
Exemplo n.º 11
0
void pwn::postfix_writer::do_print_node(pwn::print_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);
  node->argument()->accept(this, lvl); // determine the value to print
  if (is_int(node->argument()->type())) {
    _pf.CALL("printi");
    _pf.TRASH(4); // delete the printed value
    std::string *f_name = new std::string("printi");
    _declared_functions.push_back(f_name);
    _called_functions.push_back(f_name);
  }
  else if (is_string(node->argument()->type())) {
    _pf.CALL("prints");
    _pf.TRASH(4); // delete the printed value's address
    std::string *f_name = new std::string("prints");
    _declared_functions.push_back(f_name);
    _called_functions.push_back(f_name);
  } else if (is_double(node->argument()->type())) {
    _pf.CALL("printd");
    _pf.TRASH(8); // delete double printed value
    std::string *f_name = new std::string("printd");
    _declared_functions.push_back(f_name);
    _called_functions.push_back(f_name);
  } else {
    std::cerr << "ERROR: Trying to print invalid type." << std::endl;
    exit(1);
  }
  if (node->new_line()) {
    _pf.CALL("println"); // print a newline
    std::string *f_name = new std::string("println");
    _declared_functions.push_back(f_name);
    _called_functions.push_back(f_name);
  }
}
void zu::postfix_writer::do_and_node(zu::and_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);
  node->left()->accept(this, lvl);
  node->right()->accept(this, lvl);
  _pf.AND();
    
}
Exemplo n.º 13
0
void zu::postfix_writer::do_lvalue_node(zu::lvalue_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);
  // simplified generation: all variables are global
  //_pf.ADDR(node->value()); LVALUE CHANGES
    
  
}
void zu::postfix_writer::do_print_node(zu::print_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);
  node->argument()->accept(this, lvl); // determine the value to print
  if (node->argument()->type()->name() == basic_type::TYPE_INT) {
    _pf.EXTERN("printi");
    _pf.CALL("printi");
    _pf.TRASH(4); // delete the printed value
  }
  if (node->argument()->type()->name() == basic_type::TYPE_STRING) {
    _pf.EXTERN("prints");
    _pf.CALL("prints");
    _pf.TRASH(4); // delete the printed value's address
  }
  if (node->argument()->type()->name() == basic_type::TYPE_DOUBLE) {
    _pf.EXTERN("printd");
    _pf.CALL("printd");
    _pf.TRASH(8); // delete the printed value's address
  }
    /*else {
    std::cerr << "ERROR: CANNOT HAPPEN!" << std::endl;
    exit(1);
  }*/
  if (node->nl()){
    _pf.EXTERN("println");
    _pf.CALL("println"); // print a newline
  }
}
void zu::postfix_writer::do_read_node(zu::read_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);
  _pf.CALL("readi");
  _pf.PUSH();
  node->accept(this, lvl);
  _pf.STORE();
}
void zu::xml_writer::do_println_node(zu::println_node * const node, int lvl) {
  // FIXME
  CHECK_TYPES(_compiler, _symtab, node);
  openTag(node, lvl);
  node->argument()->accept(this, lvl + 2);
  closeTag(node, lvl);
}
Exemplo n.º 17
0
void pwn::postfix_writer::do_function_declaration_node(pwn::function_declaration_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);
  std::string id = fix_id(node->name());
  
  // add this function to declared functions
  _declared_functions.push_back(new std::string(id));
}
Exemplo n.º 18
0
void pwn::postfix_writer::do_function_call_node(pwn::function_call_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);

  std::string id = fix_id(node->name());
  std::shared_ptr<pwn::symbol> symbol = _symtab.find(id);
  
  // put arguments in stack (reverse order)
  int args_size = 0;
  if (node->arguments()) {
    for (int i = node->arguments()->size() - 1; i >= 0; i--) {
      node->arguments()->node(i)->accept(this, lvl);
      args_size += ((cdk::expression_node *) node->arguments()->node(i))->type()->size();
    }
  }
  
  // call function
  _pf.CALL(id);
  
  // remove arguments from stack
  _pf.TRASH(args_size);
  
  // put return value in the stack
  if (is_int(symbol->type()) || is_pointer(symbol->type()) || is_string(symbol->type())) {
    _pf.PUSH();
  } else if (is_double(symbol->type())) {
    _pf.DPUSH();
  }
  
  // add this function to called functions
  _called_functions.push_back(new std::string(id));
}
Exemplo n.º 19
0
void zu::postfix_writer::do_assignment_node(zu::assignment_node * const node, int lvl) {
    //debug(node, lvl);
  CHECK_TYPES(_compiler, _symtab, node);
/*
  // DAVID: horrible hack!
  // (this is caused by Zu not having explicit variable declarations)
  const std::string &id = node->lvalue()->value();
  std::shared_ptr<zu::symbol> symbol = _symtab.find(id);
  if (symbol->value() == -1) {
    _pf.DATA(); // variables are all global and live in DATA
    _pf.ALIGN(); // make sure we are aligned
    //_pf.LABEL(id); // name variable location 
    _pf.CONST(0); // initialize it to 0 (zero)
    _pf.TEXT(); // return to the TEXT segment
    symbol->value(0);
  }*/

  node->rvalue()->accept(this, lvl+2); // determine the new value
  if(node->rvalue()->type()->name() == basic_type::TYPE_DOUBLE)
    _pf.DDUP();
  else 
    _pf.DUP();

  node->lvalue()->accept(this, lvl+2); // where to store the value
  if(node->rvalue()->type()->name() == basic_type::TYPE_DOUBLE){
    _pf.DSTORE();
  }else{
    _pf.STORE(); // store the value at address
  }
}
void zu::postfix_writer::do_rvalue_node(zu::rvalue_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);
  node->lvalue()->accept(this, lvl);
  if(node->lvalue()->type()->name() == basic_type::TYPE_DOUBLE)
    _pf.DLOAD();
  else
    _pf.LOAD();
}
void zu::postfix_writer::do_mem_alloc_node(zu::mem_alloc_node * const node, int lvl){
    CHECK_TYPES(_compiler, _symtab, node);
    node->total_elements()->accept(this, lvl + 2);
    _pf.INT(4); // size of integer
    _pf.MUL(); // size of integer * #posicoes
    _pf.ALLOC();
    _pf.SP();
}
Exemplo n.º 22
0
void pwn::postfix_writer::do_assignment_node(pwn::assignment_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);

  node->rvalue()->accept(this, lvl); // determine the new value
  _pf.DUP();
  node->lvalue()->accept(this, lvl); // where to store the value
  _pf.STORE(); // store the value at address
}
void pwn::postfix_writer::do_neg_node(cdk::neg_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);
  node->argument()->accept(this, lvl); // determine the value
  if (node->type()->name() == basic_type::TYPE_DOUBLE)
    _pf.DNEG();
  if (node->type()->name() == basic_type::TYPE_INT)
    _pf.NEG(); // 2-complement
}
Exemplo n.º 24
0
void pwn::postfix_writer::do_index_node(pwn::index_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);
  node->expression()->accept(this, lvl); // get base address
  _pf.INT(node->shift());
  _pf.INT(8); // size of double
  _pf.MUL();
  _pf.ADD();
}
inline void zu::xml_writer::processBinaryExpression(cdk::binary_expression_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);
  openTag(node, lvl);
  if(node->left() != nullptr)
      node->left()->accept(this, lvl + 2);
  if(node->right() != nullptr)
      node->right()->accept(this, lvl + 2);
  closeTag(node, lvl);
}
Exemplo n.º 26
0
// Done
void pwn::postfix_writer::do_block_node(pwn::block_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);
  _symtab.push();
  if (node->declarations())
    node->declarations()->accept(this, lvl);
  if (node->statements())
    node->statements()->accept(this, lvl);
  _symtab.pop();
}
void zu::xml_writer::do_assignment_node(zu::assignment_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);
  openTag(node, lvl);
  node->lvalue()->accept(this, lvl + 2);
  openTag("rvalue", lvl + 2);
  node->rvalue()->accept(this, lvl + 4);
  closeTag("rvalue", lvl + 2);
  closeTag(node, lvl);
}
Exemplo n.º 28
0
void pwn::postfix_writer::do_memory_allocation_node(pwn::memory_allocation_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);
  
  node->size()->accept(this, lvl); // get number of doubles to alloc  
  _pf.INT(8);                      // size of double
  _pf.MUL();  
  _pf.ALLOC();
  _pf.SP();                        // leaves the stack pointer - address of array
}
void zu::xml_writer::do_mem_alloc_node(zu::mem_alloc_node * const node, int lvl){
  // FIXME
  CHECK_TYPES(_compiler, _symtab, node);
  openTag(node, lvl);
  openTag("total_elements", lvl + 2);
  node->total_elements()->accept(this, lvl + 4);
  closeTag("total_elements", lvl + 2);
  closeTag(node, lvl);
}
Exemplo n.º 30
0
// Done
void pwn::postfix_writer::do_if_node(cdk::if_node * const node, int lvl) {
  CHECK_TYPES(_compiler, _symtab, node);
  int lbl1;
  node->condition()->accept(this, lvl);
  _pf.JZ(mklbl(lbl1 = ++_lbl));
  node->block()->accept(this, lvl + 2);
  _pf.ALIGN();
  _pf.LABEL(mklbl(lbl1));
}