static int has_self = FALSE;
static int vararg = FALSE;
+/* destructor and initializer for variables */
+static char *destructor = NULL;
+static int destructor_line = 0;
+static gboolean destructor_simple = TRUE;
+static char *initializer = NULL;
+static int initializer_line = 0;
+
static GList *gtktypes = NULL;
/* this can be a global as we will only do one function at a time
type->postfix = postfix;
- var = new_variable(scope,type,name,line_no);
+ var = new_variable(scope, type, name, line_no,
+ destructor, destructor_line,
+ destructor_simple,
+ initializer, initializer_line);
class_nodes = g_list_append(class_nodes, var);
}
funcargs = g_list_prepend(funcargs, node);
}
+static Variable *
+find_var_or_die(const char *id, int line)
+{
+ GList *li;
+ char *s;
+
+ for(li = class_nodes; li != NULL; li = li->next) {
+ Variable *var;
+ Node *node = li->data;
+ if(node->type != VARIABLE_NODE)
+ continue;
+ var = li->data;
+ if(strcmp(var->id, id)==0)
+ return var;
+ }
+
+ s = g_strdup_printf(_("Variable %s not defined here"), id);
+ print_error(FALSE, s, line);
+
+ g_assert_not_reached();
+ return NULL;
+}
+
%}
%union {
}
;
-classcode: classcode method { ; }
- | classcode variable { ; }
- | classcode argument { ; }
- | method { ; }
+classcode: classcode thing { ; }
+ | thing { ; }
+ ;
+
+thing: method { ; }
| variable { ; }
| argument { ; }
+ | ';' { ; }
;
scope: PUBLIC { the_scope = PUBLIC_SCOPE; }
| PROTECTED { the_scope = PROTECTED_SCOPE; }
;
-variable: scope type TOKEN ';' {
- push_variable($<id>3,the_scope,$<line>1,NULL);
+destructor: TOKEN TOKEN {
+ if(strcmp($<id>1, "destroywith")==0) {
+ g_free($<id>1);
+ destructor = $<id>2;
+ destructor_line = ccode_line;
+ destructor_simple = TRUE;
+ } else {
+ g_free($<id>1);
+ g_free($<id>2);
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+ }
+ | TOKEN '{' CCODE {
+ if(strcmp($<id>1, "destroy")==0) {
+ g_free($<id>1);
+ destructor = ($<cbuf>3)->str;
+ g_string_free($<cbuf>3, FALSE);
+ destructor_line = ccode_line;
+ destructor_simple = FALSE;
+ } else {
+ g_free($<id>1);
+ g_string_free($<cbuf>3, TRUE);
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+ }
+ ;
+
+initializer: '=' numtok {
+ initializer = $<id>2;
+ initializer_line = ccode_line;
+ }
+ | '=' '{' CCODE {
+ initializer = ($<cbuf>3)->str;
+ initializer_line = ccode_line;
+ g_string_free($<cbuf>3, FALSE);
+ }
+ ;
+
+
+varoptions: destructor initializer { ; }
+ | initializer destructor { ; }
+ | initializer { destructor = NULL; }
+ | destructor { initializer = NULL; }
+ | {
+ destructor = NULL;
+ initializer = NULL;
+ }
+ ;
+
+variable: scope type TOKEN varoptions ';' {
+ push_variable($<id>3, the_scope,$<line>1, NULL);
}
- | scope type TOKEN ARRAY_DIM ';' {
- push_variable($<id>3,the_scope,$<line>1,$<id>4);
+ | scope type TOKEN ARRAY_DIM varoptions ';' {
+ push_variable($<id>3, the_scope, $<line>1, $<id>4);
}
;
argument: ARGUMENT flags argtype TOKEN TOKEN '{' CCODE TOKEN '{' CCODE ';' {
YYERROR;
}
}
+ | ARGUMENT flags argtype TOKEN TOKEN {
+ Node *node;
+ char *get, *set;
+ Variable *var;
+ Type *type;
+ char *root;
+
+ if(strcmp($<id>5,"link")!=0 &&
+ strcmp($<id>5,"stringlink")!=0 &&
+ strcmp($<id>5,"objectlink")!=0) {
+ g_free($<id>5); g_free($<id>3);
+ g_free($<id>4);
+ g_list_foreach($<list>2,(GFunc)g_free,NULL);
+ yyerror(_("parse error"));
+ YYERROR;
+ }
+
+ type = pop_type();
+
+ var = find_var_or_die($<id>4, $<line>1);
+ if(var->scope == PRIVATE_SCOPE)
+ root = "self->_priv";
+ else
+ root = "self";
+
+ if(strcmp($<id>5,"link")==0) {
+ set = g_strdup_printf("%s->%s = ARG;",
+ root, $<id>4);
+ } else if(strcmp($<id>5,"stringlink")==0) {
+ set = g_strdup_printf("g_free(%s->%s); "
+ "%s->%s = g_strdup(ARG);",
+ root, $<id>4,
+ root, $<id>4);
+ } else if(strcmp($<id>5,"objectlink")==0) {
+ set = g_strdup_printf(
+ "if(%s->%s) "
+ "gtk_object_unref(GTK_OBJECT(%s->%s)); "
+ "%s->%s = ARG; "
+ "if(%s->%s) "
+ "gtk_object_ref(GTK_OBJECT(%s->%s)); ",
+ root, $<id>4,
+ root, $<id>4,
+ root, $<id>4,
+ root, $<id>4,
+ root, $<id>4);
+ } else {
+ g_assert_not_reached();
+ }
+
+ /* get is the same for everything */
+ get = g_strdup_printf("ARG = %s->%s;", root, $<id>4);
+
+ g_free($<id>5);
+
+
+ if(!type)
+ type = copy_type(var->vtype);
+
+ node = new_argument($<id>3, type, $<list>2,
+ $<id>4, get, $<line>1,
+ set, $<line>1, $<line>1);
+ class_nodes = g_list_append(class_nodes,node);
+ }
;
argtype: TOKEN '(' TOKEN type ')' {