void CCodeGenerator::operator()(Construct* expr) { // Look up the function by name in the current context. String::Ptr id = env_->name("@init"); Class::Ptr clazz = expr->type()->clazz(); Function::Ptr func = clazz->function(id); std::vector<Operand> args; for (Expression::Ptr a = expr->arguments(); a; a = a->next()) { args.push_back(emit(a)); } return_ = alloc_temp(clazz->type()); out_ << func->label() << "("; Formal::Ptr formal = func->formals(); Expression::Ptr arg = expr->arguments(); for (int i = 0; i < args.size(); i++) { if(!formal->is_self() && !formal->type()->equals(arg->type())) { // Cast to the appropriate C-type, since C doesn't know anything // about subtypes, etc.. out_ << "("; operator()(formal->type()); out_ << ")"; } out_ << args[i]; if (i < args.size() - 1) { out_ << ", "; } formal = formal->next(); arg = arg->next(); } out_ << ");\n"; }
void CCodeGenerator::native_operator(Call* expr) { std::string id = expr->function()->name()->string(); std::vector<Operand> args; for (Expression::Ptr a = expr->arguments(); a; a = a->next()) { args.push_back(emit(a)); } return_ = alloc_temp(expr->type()); if (id == "@add") { out_ << args[0] << "+" << args[1] << ";\n"; } else if (id == "@sub") { out_ << args[0] << "-" << args[1] << ";\n"; } else if (id == "@mul") { out_ << args[0] << "*" << args[1] << ";\n"; } else if (id == "@div") { out_ << args[0] << "/" << args[1] << ";\n"; } else if (id == "@neg") { out_ << "-" << args[0] << ";\n"; } else if (id == "@mod") { out_ << args[0] << "%" << args[1] << ";\n"; } else if (id == "@compl") { out_ << "~" << args[0] << ";\n"; } else if (id == "@equal") { out_ << args[0] << "==" << args[1] << ";\n"; } else if (id == "@less") { out_ << args[0] << "<" << args[1] << ";\n"; } }
void CCodeGenerator::call(Function* function, Expression* args) { std::vector<Operand> val; for (Expression::Ptr a = args; a; a = a->next()) { val.push_back(emit(a)); } if (!function->type()->is_void()) { return_ = alloc_temp(function->type()); } else { line(); } out_ << function->label() << "("; Expression::Ptr arg = args; Formal::Ptr formal = function->formals(); for (int i = 0; i < val.size(); i++) { if(!formal->is_self() && !formal->type()->equals(arg->type())) { // Cast to the appropriate C-type, since C doesn't know anything // about subtypes, etc.. out_ << "("; operator()(formal->type()); out_ << ")"; } out_ << val[i]; if (i < val.size() - 1) { out_ << ", "; } formal = formal->next(); arg = arg->next(); } out_ << ");\n"; }
// returns a pointer the the new beginning of the temp memory void * resize_temp(size_t size) { if (temp_end == 0) return alloc_temp(size); if (bottom + size <= top) { temp_end = bottom + size; } else { size_t s = temp_end - bottom; byte * p = bottom; new_chunk(); memcpy(bottom, p, s); temp_end = bottom + size; } return bottom; }
void CCodeGenerator::operator()(IdentifierRef* expr) { // Simply look up the value of the variable as stored previously. String::Ptr id = expr->identifier(); Variable::Ptr var = variable(id); Attribute::Ptr attr = class_ ? class_->attribute(id) : 0; if (var) { return_ = Operand(id.pointer()); } else if (attr) { return_ = alloc_temp(expr->type()); out_ << "self->" << id->string() << ";\n"; } else { return_ = Operand(id.pointer()); } }
// returns a pointer to the beginning of the new memory (in // otherwords the END of the temp memory BEFORE the call to grow // temp) NOT the beginning if the temp memory void * grow_temp(size_t s) { if (temp_end == 0) return alloc_temp(s); unsigned old_size = temp_end - bottom; unsigned size = old_size + s; if (bottom + size <= top) { temp_end = bottom + size; } else { size_t s = temp_end - bottom; byte * p = bottom; new_chunk(); memcpy(bottom, p, s); temp_end = bottom + size; } return bottom + old_size; }
GdkRectangle * SvGdkRectangle(SV * data, GdkRectangle * rect) { AV * a; SV ** s; if ((!data) || (!SvOK(data)) || (!SvRV(data)) || (SvTYPE(SvRV(data)) != SVt_PVAV)) return 0; a = (AV*)SvRV(data); if (av_len(a) != 3) croak("rectangle must have four elements"); if (!rect) rect = alloc_temp(sizeof(GdkRectangle)); rect->x = SvIV(*av_fetch(a, 0, 0)); rect->y = SvIV(*av_fetch(a, 1, 0)); rect->width = SvIV(*av_fetch(a, 2, 0)); rect->height = SvIV(*av_fetch(a, 3, 0)); return rect; }
void CCodeGenerator::operator()(StringLiteral* expression) { return_ = alloc_temp(expression->type()); out_ << "&lit" << (void*)expression->value() << ";\n"; }
GdkWindowAttr * SvGdkWindowAttr(SV * data, GdkWindowAttr * attr, gint * mask) { HV * h; SV ** s; if ((!data) || (!SvOK(data)) || (!SvRV(data)) || (SvTYPE(SvRV(data)) != SVt_PVHV)) return 0; if (!attr) attr = alloc_temp(sizeof(GdkWindowAttr)); memset(attr, 0, sizeof(GdkWindowAttr)); *mask = 0; h = (HV*)SvRV(data); if (s=hv_fetch(h, "title", 5, 0)) { attr->title = SvPV(*s,PL_na); *mask |= GDK_WA_TITLE; } if (s=hv_fetch(h, "x", 1, 0)) { attr->x = SvIV(*s); *mask |= GDK_WA_X; } if (s=hv_fetch(h, "y", 1, 0)) { attr->y = SvIV(*s); *mask |= GDK_WA_Y; } if (s=hv_fetch(h, "cursor", 6, 0)) { attr->cursor = SvGdkCursorRef(*s); *mask |= GDK_WA_CURSOR; } if (s=hv_fetch(h, "colormap", 8, 0)) { attr->colormap = SvGdkColormap(*s); *mask |= GDK_WA_COLORMAP; } if (s=hv_fetch(h, "visual", 6, 0)) { attr->visual = SvGdkVisual(*s); *mask |= GDK_WA_VISUAL; } if (s=hv_fetch(h, "window_type",11, 0)) attr->window_type = SvGdkWindowType(*s); else croak("window attribute must have window_type"); if (s=hv_fetch(h, "event_mask",10, 0)) attr->event_mask = SvGdkEventMask(*s); else croak("window attribute must have event_mask"); if (s=hv_fetch(h, "width",5, 0)) attr->width = SvIV(*s); else croak("window attribute must have width"); if (s=hv_fetch(h, "height",6, 0)) attr->height = SvIV(*s); else croak("window attribute must have height"); if (s=hv_fetch(h, "wclass",6, 0)) attr->wclass = SvGdkWindowClass(*s); else attr->wclass = GDK_INPUT_OUTPUT; return attr; }
GdkEvent * SvSetGdkEvent(SV * data, GdkEvent * e) { HV * h; SV ** s; if (!data || !SvOK(data) || !(h=(HV*)SvRV(data)) || (SvTYPE(h) != SVt_PVHV)) return 0; if (!e) e = alloc_temp(sizeof(GdkEvent)); s = hv_fetch(h, "_ptr", 4, 0); if (!s || !SvIV(*s)) croak("event is damaged"); e = (GdkEvent*)SvIV(*s); /*printf("Composing GdkEvent HV %d to pointer %d\n", h, e);*/ if (s=hv_fetch(h, "type", 4, 0)) e->type = SvGdkEventType(*s); else croak("event must contain type"); if (s=hv_fetch(h, "window", 6, 0)) e->any.window = SvGdkWindow(*s); else croak("event must contain window"); switch (e->type) { case GDK_EXPOSE: if (s=hv_fetch(h, "area", 4, 0)) SvGdkRectangle(*s, &e->expose.area); else croak("event must contain area"); if (s=hv_fetch(h, "count", 5, 0)) e->expose.count = SvIV(*s); else croak("event must contain count"); break; case GDK_MOTION_NOTIFY: if (s=hv_fetch(h, "x", 1, 0)) e->motion.x = SvNV(*s); else croak("event must contain x ordinate"); if (s=hv_fetch(h, "y", 1, 0)) e->motion.y = SvNV(*s); else croak("event must contain y ordinate"); if (s=hv_fetch(h, "pressure", 8, 0)) e->button.button = SvNV(*s); else e->button.pressure = 0; if (s=hv_fetch(h, "xtilt", 5, 0)) e->button.xtilt = SvNV(*s); else e->button.xtilt = 0; if (s=hv_fetch(h, "ytilt", 5, 0)) e->button.ytilt = SvNV(*s); else e->button.ytilt = 0; if (s=hv_fetch(h, "ytilt", 5, 0)) e->button.ytilt = SvNV(*s); else e->button.ytilt = 0; if (s=hv_fetch(h, "time", 4, 0)) e->motion.time = SvIV(*s); else croak("event must contain time"); if (s=hv_fetch(h, "state", 5, 0)) e->motion.state = SvIV(*s); else croak("event must contain state"); if (s=hv_fetch(h, "is_hint", 7, 0)) e->motion.is_hint = SvIV(*s); else croak("event must contain is_hint"); if (s=hv_fetch(h, "source", 6, 0)) e->button.source = SvGdkInputSource(*s); else e->button.source = 0; if ((s=hv_fetch(h, "deviceid", 8, 0)) && SvOK(*s)) e->button.deviceid = SvIV(*s); else e->button.deviceid = GDK_CORE_POINTER; break; case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: case GDK_BUTTON_RELEASE: if (s=hv_fetch(h, "x", 1, 0)) e->button.x = SvNV(*s); else croak("event must contain x ordinate"); if (s=hv_fetch(h, "y", 1, 0)) e->button.y = SvNV(*s); else croak("event must contain y ordinate"); if (s=hv_fetch(h, "pressure", 8, 0)) e->button.button = SvNV(*s); else e->button.pressure = 0; if (s=hv_fetch(h, "xtilt", 5, 0)) e->button.xtilt = SvNV(*s); else e->button.xtilt = 0; if (s=hv_fetch(h, "ytilt", 5, 0)) e->button.ytilt = SvNV(*s); else e->button.ytilt = 0; if (s=hv_fetch(h, "ytilt", 5, 0)) e->button.ytilt = SvNV(*s); else e->button.ytilt = 0; if (s=hv_fetch(h, "time", 4, 0)) e->button.time = SvIV(*s); else croak("event must contain time"); if (s=hv_fetch(h, "state", 5, 0)) e->button.state = SvIV(*s); else croak("event must contain state"); if (s=hv_fetch(h, "button", 6, 0)) e->button.button = SvIV(*s); else croak("event must contain state"); if (s=hv_fetch(h, "source", 6, 0)) e->button.source = SvGdkInputSource(*s); else e->button.source = 0; if ((s=hv_fetch(h, "deviceid", 8, 0)) && SvOK(*s)) e->button.deviceid = SvIV(*s); else e->button.deviceid = GDK_CORE_POINTER; break; case GDK_KEY_PRESS: case GDK_KEY_RELEASE: if (s=hv_fetch(h, "time", 4, 0)) e->key.time = SvIV(*s); else croak("event must contain time"); if (s=hv_fetch(h, "state", 5, 0)) e->key.state = SvIV(*s); else croak("event must contain state"); if (s=hv_fetch(h, "keyval", 6, 0)) e->key.keyval = SvIV(*s); else croak("event must contain keyval"); case GDK_FOCUS_CHANGE: if (s=hv_fetch(h, "in", 2, 0)) e->focus_change.in = SvIV(*s); else croak("event must contain in"); break; case GDK_ENTER_NOTIFY: case GDK_LEAVE_NOTIFY: if (s=hv_fetch(h, "window", 6, 0)) e->crossing.window = SvGdkWindow(*s); else croak("event must contain window"); if (s=hv_fetch(h, "subwindow", 9, 0)) e->crossing.subwindow = SvGdkWindow(*s); else croak("event must contain subwindow"); if (s=hv_fetch(h, "detail", 6, 0)) e->crossing.detail = SvGdkNotifyType(*s); else croak("event must contain detail"); break; case GDK_CONFIGURE: if (s=hv_fetch(h, "x", 1, 0)) e->configure.x = SvIV(*s); else croak("event must contain x ordinate"); if (s=hv_fetch(h, "y", 1, 0)) e->configure.y = SvIV(*s); else croak("event must contain y ordinate"); if (s=hv_fetch(h, "width", 5, 0)) e->configure.width = SvIV(*s); else croak("event must contain width"); if (s=hv_fetch(h, "height", 6, 0)) e->configure.height = SvIV(*s); else croak("event must contain height"); break; case GDK_PROPERTY_NOTIFY: if (s=hv_fetch(h, "time", 4, 0)) e->property.time = SvIV(*s); else croak("event must contain time"); if (s=hv_fetch(h, "state", 5, 0)) e->property.state = SvIV(*s); else croak("event must contain state"); if (s=hv_fetch(h, "atom", 4, 0)) e->property.atom = SvGdkAtom(*s); else croak("event must contain atom"); break; case GDK_SELECTION_CLEAR: case GDK_SELECTION_REQUEST: case GDK_SELECTION_NOTIFY: if (s=hv_fetch(h, "requestor", 9, 0)) e->selection.requestor = SvIV(*s); else croak("event must contain requestor"); if (s=hv_fetch(h, "time", 4, 0)) e->selection.time = SvIV(*s); else croak("event must contain time"); if (s=hv_fetch(h, "selection", 9, 0)) e->selection.selection = SvGdkAtom(*s); else croak("event must contain selection"); if (s=hv_fetch(h, "property", 8, 0)) e->selection.property = SvGdkAtom(*s); else croak("event must contain property"); break; case GDK_PROXIMITY_IN: case GDK_PROXIMITY_OUT: if (s=hv_fetch(h, "time", 4, 0)) e->proximity.time = SvIV(*s); else croak("event must contain time"); if (s=hv_fetch(h, "deviceid", 8, 0)) e->proximity.deviceid = SvIV(*s); else croak("event must contain deviceid"); break; } return e; }
GdkGCValues * SvGdkGCValues(SV * data, GdkGCValues * v, GdkGCValuesMask * m) { HV * h; SV ** s; if ((!data) || (!SvOK(data)) || (!SvRV(data)) || (SvTYPE(SvRV(data)) != SVt_PVHV)) return 0; h = (HV*)SvRV(data); if (!v) v = alloc_temp(sizeof(GdkGCValues)); memset(v,0,sizeof(GdkGCValues)); if ((s=hv_fetch(h, "foreground", 10, 0)) && SvOK(*s)) { SvSetGdkColor(*s, &v->foreground); *m |= GDK_GC_FOREGROUND; } if ((s=hv_fetch(h, "background", 10, 0)) && SvOK(*s)) { SvSetGdkColor(*s, &v->background); *m |= GDK_GC_BACKGROUND; } if ((s=hv_fetch(h, "font", 4, 0)) && SvOK(*s)) { v->font = SvMiscRef(*s, "Gtk::Gdk::Font"); *m |= GDK_GC_FONT; } if ((s=hv_fetch(h, "function", 8, 0)) && SvOK(*s)) { v->function = SvGdkFunction(*s); *m |= GDK_GC_FUNCTION; } if ((s=hv_fetch(h, "fill", 4, 0)) && SvOK(*s)) { v->function = SvGdkFill(*s); *m |= GDK_GC_FILL; } if ((s=hv_fetch(h, "tile", 4, 0)) && SvOK(*s)) { v->tile = SvMiscRef(*s, "Gtk::Gdk::Pixmap"); *m |= GDK_GC_TILE; } if ((s=hv_fetch(h, "stipple", 7, 0)) && SvOK(*s)) { v->stipple = SvMiscRef(*s, "Gtk::Gdk::Pixmap"); *m |= GDK_GC_STIPPLE; } if ((s=hv_fetch(h, "clip_mask", 9, 0)) && SvOK(*s)) { v->clip_mask = SvMiscRef(*s, "Gtk::Gdk::Pixmap"); *m |= GDK_GC_CLIP_MASK; } if ((s=hv_fetch(h, "subwindow_mode", 14, 0)) && SvOK(*s)) { v->subwindow_mode = SvGdkSubwindowMode(*s); *m |= GDK_GC_SUBWINDOW; } if ((s=hv_fetch(h, "ts_x_origin", 11, 0)) && SvOK(*s)) { v->ts_x_origin = SvIV(*s); *m |= GDK_GC_TS_X_ORIGIN; } if ((s=hv_fetch(h, "ts_y_origin", 11, 0)) && SvOK(*s)) { v->ts_y_origin = SvIV(*s); *m |= GDK_GC_TS_Y_ORIGIN; } if ((s=hv_fetch(h, "clip_x_origin", 13, 0)) && SvOK(*s)) { v->clip_x_origin = SvIV(*s); *m |= GDK_GC_CLIP_X_ORIGIN; } if ((s=hv_fetch(h, "clip_y_origin", 13, 0)) && SvOK(*s)) { v->clip_y_origin = SvIV(*s); *m |= GDK_GC_CLIP_Y_ORIGIN; } if ((s=hv_fetch(h, "graphics_exposures", 18, 0)) && SvOK(*s)) { v->graphics_exposures = SvIV(*s); *m |= GDK_GC_EXPOSURES; } if ((s=hv_fetch(h, "line_width", 10, 0)) && SvOK(*s)) { v->line_width= SvIV(*s); *m |= GDK_GC_LINE_WIDTH; } if ((s=hv_fetch(h, "line_style", 10, 0)) && SvOK(*s)) { v->line_style= SvGdkLineStyle(*s); *m |= GDK_GC_LINE_STYLE; } if ((s=hv_fetch(h, "cap_style", 9, 0)) && SvOK(*s)) { v->cap_style = SvGdkCapStyle(*s); *m |= GDK_GC_CAP_STYLE; } if ((s=hv_fetch(h, "join_style", 10, 0)) && SvOK(*s)) { v->join_style = SvGdkJoinStyle(*s); *m |= GDK_GC_JOIN_STYLE; } return v; }