Again modified the formatting stuff. Some preliminary header stuff.

Soon moving to use cpp..
This commit is contained in:
Lauri Alanko 1998-11-19 22:36:44 +00:00
parent b593a1592f
commit 51b4b0966e
16 changed files with 581 additions and 441 deletions

View File

@ -1,3 +1,8 @@
1998-11-20 Lauri Alanko <la@iki.fi>
* Again modified the formatting stuff. Some preliminary header
stuff. Soon moving to use cpp..
1998-11-18 Lauri Alanko <la@iki.fi>
* Signal marshalling should be pretty complete now. Demarshalling

View File

@ -1,8 +1,8 @@
noinst_PROGRAMS = gcg
CFLAGS=-I/usr/local/lib/glib/include -DYYDEBUG=1 -g -Wall -W -DCPP="$(CPP)"
INCLUDES = -DYYDEBUG=1 @GLIB_CFLAGS@
CFLAGS=-g -Wall -W -DCPP="$(CPP)" -ansi -pedantic
INCLUDES = @GLIB_CFLAGS@
YFLAGS = -d -v 2>/dev/null
LIBS = @GLIB_LIBS@

View File

@ -1,72 +1,47 @@
#include "gcg.h"
static GHashTable* module_hash;
static GHashTable* package_hash = NULL;
static GSList* def_list = NULL;
void init_db(void){
module_hash=g_hash_table_new(NULL, NULL);
package_hash = g_hash_table_new(NULL, NULL);
}
PrimType* get_type(Id modname, Id name){
Module* m = get_mod(modname);
PrimType* p = g_hash_table_lookup(m->decl_hash, name);
if(!p){
p=g_new(PrimType, 1);
p->module=m;
p->name=name;
p->kind=TYPE_INVALID;
p->decl_header=NULL;
p->def_header=NULL;
p->definition=NULL;
g_hash_table_insert(m->decl_hash, name, p);
}
return p;
PrimType* get_type(Package* pkg, Id name){
return g_hash_table_lookup(pkg->type_hash, name);
}
void put_type(PrimType* t){
g_hash_table_insert(t->module->package->type_hash,
(gpointer)t->name, t);
}
void put_def(Def* d){
PrimType* t=d->type;
g_assert(t);
t->definition=d;
def_list = g_slist_append (def_list, d);
}
Def* get_def(Id modname, Id type){
PrimType* t=get_type(modname, type);
g_assert(t);
return t->definition;
Package* get_pkg(Id pkgname){
return g_hash_table_lookup(package_hash, pkgname);
}
Module* get_mod(Id modname){
Module* m=g_hash_table_lookup(module_hash, modname);
if(!m){
m=g_new(Module, 1);
m->name=modname;
m->decl_hash=g_hash_table_new(NULL, NULL);
m->common_header=NULL;
g_hash_table_insert(module_hash, modname, m);
}
return m;
void put_pkg(Package* pkg){
g_hash_table_insert(package_hash, (gpointer)pkg->name, pkg);
}
typedef struct{
DefFunc f;
gpointer user_data;
}DFEdata;
void dfe_bar(gpointer key, gpointer p, gpointer foo){
PrimType* t=p;
DFEdata* d=foo;
if(t->definition)
(d->f)(t->definition, d->user_data);
Module* get_mod(Package* pkg, Id modname){
return g_hash_table_lookup(pkg->mod_hash, modname);
}
void dfe_foo(gpointer key, gpointer p, gpointer dfed){
Module* m=p;
g_hash_table_foreach(m->decl_hash, dfe_bar, dfed);
void put_mod(Module* m){
g_hash_table_insert(m->package->mod_hash, (gpointer)m->name, m);
}
void foreach_def(DefFunc f, gpointer user_data){
DFEdata d={f,user_data};
g_hash_table_foreach(module_hash, dfe_foo, &d);
};
GSList* l = def_list;
while(l){
f(l->data, user_data);
l = l->next;
}
}

View File

@ -2,9 +2,17 @@
#include "parser.h"
#include <stdio.h>
#include <glib.h>
#define __USE_POSIX2
#include <unistd.h>
#include "output.h"
#ifndef CPP
#define CPP "cpp"
#endif
Type* type_gtk_type;
Id func_hdr_name;
@ -54,11 +62,6 @@ void output_cb(Def* def, gpointer out){
int main(int argc, char* argv[]){
/* target=stdout;*/
PRoot* out=pr_new();
const gchar* tag_type="type";
const gchar* tag_source="source";
const gchar* tag_source_head="source_head";
const gchar* tag_functions="functions";
const gchar* tag_protected="protected";
FILE* f;
init_db();
@ -67,23 +70,20 @@ int main(int argc, char* argv[]){
yyin=fopen(argv[optind], "r");
g_assert(yyin);
yyparse();
type_gtk_type=g_new(Type, 1);
type_gtk_type->is_const=FALSE;
type_gtk_type->indirection=0;
type_gtk_type->notnull=FALSE;
type_gtk_type->prim=get_type(GET_ID("Gtk"), GET_ID("Type"));
g_assert(type_gtk_type->prim);
foreach_def(output_cb, out);
f=fopen(type_hdr_name, "w+");
pr_write(out, f, &tag_type, 1);
pr_write(out, f, "type");
f=fopen(source_name, "w+");
pr_write(out, f, &tag_source_head, 1);
pr_write(out, f, &tag_source, 1);
pr_write(out, f, "source_deps");
pr_write(out, f, "source_head");
pr_write(out, f, "source");
f=fopen(func_hdr_name, "w+");
pr_write(out, f, &tag_functions, 1);
pr_write(out, f, "func_deps");
pr_write(out, f, "functions");
f=fopen(prot_hdr_name, "w+");
pr_write(out, f, &tag_protected, 1);
pr_write(out, f, "prot_deps");
pr_write(out, f, "protected");
return 0;
}

View File

@ -23,6 +23,7 @@ typedef struct _MemberClass MemberClass;
typedef struct _DefClass DefClass;
typedef struct _Param Param;
typedef struct _Module Module;
typedef struct _Package Package;
typedef enum{
TYPE_INVALID,
@ -36,19 +37,23 @@ typedef enum{
TYPE_OBJECT
} TypeKind;
struct _Module {
struct _Package {
Id name;
Id common_header;
GHashTable* decl_hash;
GHashTable* type_hash;
GHashTable* mod_hash;
};
struct _Module {
Package* package;
Id name;
Id header;
};
struct _PrimType {
Module* module;
Id name;
TypeKind kind;
Id decl_header;
Id def_header;
Def* definition;
};
struct _Type {
@ -114,7 +119,7 @@ typedef enum _EmitDef{
typedef enum _MemberType{
MEMBER_DATA,
MEMBER_METHOD,
MEMBER_METHOD
} MemberType;
typedef enum _DataMemberKind{
@ -168,18 +173,14 @@ typedef void (*DefFunc)(Def* def, gpointer user_data);
void init_db(void);
void put_decl(PrimType* t);
PrimType* get_type(Package* pkg, Id type);
void put_type(PrimType* t);
Package* get_pkg(Id pkgname);
void put_pkg(Package* pkg);
Module* get_mod(Package* pkg, Id module);
void put_mod(Module* m);
void put_def(Def* d);
PrimType* get_type(Id module, Id type);
Def* get_def(Id module, Id type);
Module* get_mod(Id module);
void foreach_def(DefFunc f, gpointer user_data);
extern Type* type_gtk_type;
#endif

View File

@ -1,42 +1,21 @@
// this is just a simple test input file
module g {
@int int;
};
#include <gimp.gh>
module Gtk {
@int Type;
};
module Gimp{
class Object;
class Layer;
class Drawable;
class Image;
enum ImageType;
enum ChannelType;
enum BaseType;
};
module Gimp.Image;
import g;
module Gimp;
enum ImageType{
rgb, rgba, gray, graya, indexed, indexeda
};
enum ChannelType{
red, green, blue, gray, indexed, auxillary
};
enum BaseType{
rgb, gray, indexed
};
enum ImageType {rgb, rgba, gray, graya, indexed, indexeda}
enum ChannelType {red, green, blue, gray, indexed, auxillary}
enum BaseType {rgb, gray, indexed}
class Image : Object{
read-only g.int width;
read-only g.int height;
g.int num-cols;
read-only int width;
read-only int height;
int num-cols;
read-only BaseType base-type;
read-write g.int foobar;
read-write int foobar;
read-write Layer& active-layer;
read-write Layer* floating-sel;
public static Image* new(g.int width,
@ -49,16 +28,16 @@ class Image : Object{
protected pre-emit void foo-4(g.int x) const;
public post-emit g.int foo-5(g.int x, Drawable**& n, Image* z);
public post-emit g.int foo-6(g.int a1,
g.int a2,
g.int a3,
g.int a4,
g.int a5,
g.int a6,
g.int a7,
g.int a8,
g.int a9,
g.int a10,
g.int a11,
g.int a12,
g.int a13);
};
g.int a2,
g.int a3,
g.int a4,
int a5,
g.int a6,
g.int a7,
g.int a8,
g.int a9,
g.int a10,
g.int a11,
g.int a12,
g.int a13);
}

View File

@ -1,10 +1,12 @@
%option noyywrap
%option yylineno
%{
#include "gcg.h"
#include "parser.h"
%}
ident [A-Za-z][A-Za-z0-9-]*
header <[[:alnum:]/.]+>
ws [ \n\t\r]
@ -20,6 +22,7 @@ static return T_STATIC;
protected return T_PROTECTED;
pre-emit return T_PRE_EMIT;
post-emit return T_POST_EMIT;
mid-emit return T_DUAL_EMIT;
read-only return T_READ_ONLY;
read-write return T_READ_WRITE;
private return T_PRIVATE;
@ -32,6 +35,7 @@ module return T_MODULE;
import return T_IMPORT;
header return T_HEADER;
opaque return T_OPAQUE;
package return T_PACKAGE;
void return T_VOID;
enum return T_ENUM;
@ -39,6 +43,7 @@ flags return T_FLAGS;
@int return T_INT;
real return T_DOUBLE;
boxed return T_BOXED;
foreign return T_FOREIGN;
{ident} {
@ -56,7 +61,9 @@ boxed return T_BOXED;
}
{header} {
yylval.id=g_quark_to_string(g_quark_from_string(yytext));
gchar* tmp = g_strndup(&yytext[1], yyleng-2);
yylval.id=g_quark_to_string(g_quark_from_string(tmp));
g_free (tmp);
return T_HEADERNAME;
}

View File

@ -46,7 +46,7 @@ MarshallType marshalling_type(Type* t){
SignalType* sig_type(Method* m){
SignalType *t=g_new(SignalType, 1);
GSList* p=m->params, *a=NULL;
t->package = DEF(MEMBER(m)->my_class)->type->module->name;
t->package = DEF(MEMBER(m)->my_class)->type->module->package->name;
t->rettype = marshalling_type(&m->ret_type);
while(p){
Param* param=p->data;
@ -152,7 +152,7 @@ PNode* p_handler_type(SignalType* t){
PNode* p_signal_id(Method* s){
PrimType* t=DEF(MEMBER(s)->my_class)->type;
return p_fmt("_~_~_signal_~",
p_c_ident(t->module->name),
p_c_ident(t->module->package->name),
p_c_ident(t->name),
p_c_ident(MEMBER(s)->name));
}
@ -219,7 +219,8 @@ PNode* p_demarshaller(SignalType* t){
gint idx=0;
return p_lst((t->rettype==TYPE_NONE)
return p_fmt("~~",
(t->rettype==TYPE_NONE)
? p_fmt("\t*(GTK_RETLOC_~(args[~])) =\n",
p_gtype_name(t->rettype, FALSE),
p_prf("%d", g_slist_length(t->argtypes)))
@ -228,8 +229,7 @@ PNode* p_demarshaller(SignalType* t){
"~"
"\tuser_data);\n",
p_cast(p_handler_type(t), p_str("func")),
p_for(t->argtypes, p_arg_demarsh, &idx)),
p_nil);
p_for(t->argtypes, p_arg_demarsh, &idx)));
}

View File

@ -39,18 +39,41 @@ PNode* p_c_macro(Id id){
}
PNode* p_param(FunParams* p, ParamOptions* opt){
return p_lst(opt->first ? p_nil : p_str(", "),
return p_fmt("~~~~",
opt->first ? p_nil : p_str(", "),
opt->types ? p_type(&p->type) : p_nil,
opt->types && opt->names ? p_str(" ") : p_nil,
opt->names ? p->name : p_nil,
NULL);
opt->names ? p->name : p_nil);
}
PNode* p_prot_header(Module* m){
if(m->header)
return p_str(m->header);
else
return p_fmt("~/~_p.h",
p_c_ident(m->package->name),
p_c_ident(m->name));
}
PNode* p_type_header(Module* m){
if(m->header)
return p_str(m->header);
else
return p_fmt("~/~_t.h",
p_c_ident(m->package->name),
p_c_ident(m->name));
}
PNode* p_type_include(Module* m){
return p_fmt("#include <~>\n",
p_type_header(m));
}
PNode* p_params(FunParams* args, ParamOptions* opt){
ParamOptions o=*opt;
PNode* n=p_nil;
while(args){
n=p_lst(n, p_param(args, &o), NULL);
n=p_fmt("~~", n, p_param(args, &o));
args=args->next;
o.first=FALSE;
}
@ -68,9 +91,9 @@ PNode* p_prim_varname(PrimType* t){
}
PNode* p_primtype(PrimType* t){
return p_lst(p_str(t->module->name),
p_str(t->name),
NULL);
return p_fmt("~~",
p_str(t->module->package->name),
p_str(t->name));
}
PNode* p_cast(PNode* force_type, PNode* expression){
@ -87,7 +110,7 @@ PNode* p_type(Type* t){
t->is_const ? p_str("const ") : p_nil,
p_primtype(t->prim));
while(i--)
node=p_lst(node, p_str("*"), NULL);
node=p_fmt("~~", node, p_str("*"));
/* file_add_dep(s, t->prim->decl_header);*/
return node;
}else
@ -102,7 +125,7 @@ PNode* p_self_type(ObjectDef* o, PBool const_self){
PNode* p_varname(PrimType* t, PNode* name){
return p_fmt("~_~_~",
p_c_ident(t->module->name),
p_c_ident(t->module->package->name),
p_c_ident(t->name),
name);
}
@ -125,37 +148,36 @@ PNode* p_type_guard(Type* t, PNode* var){
kind !=
*/
return p_lst
((t->indirection && t->notnull
? p_fmt("\tg_assert (~);\n", var)
: p_nil),
((t->indirection==1 && p->kind == TYPE_OBJECT)
? (t->notnull
? p_fmt("\tg_assert (~(~));\n",
p_macro_name(p, "IS", NULL),
var)
: p_fmt("\tg_assert (!~ || ~(~));\n",
var,
p_macro_name(p, "IS", NULL),
var))
: (t->indirection==0
? ((p->kind == TYPE_ENUM)
? p_fmt("\tg_assert (~ <= ~);\n",
var,
p_macro_name(p, NULL, "LAST"))
: ((p->kind == TYPE_FLAGS)
? p_fmt("\tg_assert ((~ << 1) < ~);\n",
var,
p_macro_name(p, NULL, "LAST"))
: p_nil))
: p_nil)),
NULL);
return p_fmt("~~",
(t->indirection && t->notnull
? p_fmt("\tg_assert (~);\n", var)
: p_nil),
((t->indirection==1 && p->kind == TYPE_OBJECT)
? (t->notnull
? p_fmt("\tg_assert (~(~));\n",
p_macro_name(p, "IS", NULL),
var)
: p_fmt("\tg_assert (!~ || ~(~));\n",
var,
p_macro_name(p, "IS", NULL),
var))
: (t->indirection==0
? ((p->kind == TYPE_ENUM)
? p_fmt("\tg_assert (~ <= ~);\n",
var,
p_macro_name(p, NULL, "LAST"))
: ((p->kind == TYPE_FLAGS)
? p_fmt("\tg_assert ((~ << 1) < ~);\n",
var,
p_macro_name(p, NULL, "LAST"))
: p_nil))
: p_nil)));
}
PNode* p_type_guards(FunParams* args){
PNode* p=p_nil;
while(args){
p=p_lst(p, p_type_guard(&args->type, args->name), NULL);
p=p_fmt("~~", p, p_type_guard(&args->type, args->name));
args=args->next;
}
return p;
@ -164,7 +186,11 @@ PNode* p_type_guards(FunParams* args){
PNode* p_prototype(Type* rettype, PNode* name,
PNode* args1,
FunParams* args2){
ParamOptions o={(!args1 || args1==p_nil), TRUE, TRUE};
ParamOptions o;
o.first = !args1 || args1 == p_nil;
o.names = TRUE;
o.types = TRUE;
return p_fmt("~ ~ (~~)",
p_type(rettype),
name,
@ -176,14 +202,14 @@ void output_var_alias(PRoot* out, PrimType* t, PNode* basename){
pr_add(out, "import_alias",
p_fmt("#define ~ ~_~\n",
basename,
p_c_ident(t->module->name),
p_c_ident(t->module->package->name),
basename));
}
void output_type_alias(PRoot* out, PrimType* t, PNode* basename){
pr_add(out, "import_alias",
p_fmt("typedef ~~ ~;\n",
p_str(t->module->name),
p_str(t->module->package->name),
basename,
basename));
}
@ -218,10 +244,10 @@ void output_func(PRoot* out,
PNode* p_macro_name(PrimType* t, Id mid, Id post){
return p_fmt("~~_~~",
p_c_macro(t->module->name),
mid ? p_lst(p_str("_"), p_c_macro(mid), NULL) : p_nil,
p_c_macro(t->module->package->name),
mid ? p_fmt("_~", p_c_macro(mid)) : p_nil,
p_c_macro(t->name),
post ? p_lst(p_str("_"), p_c_macro(post), NULL) : p_nil);
post ? p_fmt("_~", p_c_macro(post)) : p_nil);
}
void output_var(PRoot* out, Id tag, PNode* type, PNode* name){
@ -247,11 +273,11 @@ void output_def(PRoot* out, Def* d){
pr_add(out, "protected", p_str("\n\n"));
pr_add(out, "source_head", p_str("\n"));
pr_add(out, "type", p_fmt("#define ~ \\\n"
" (~ ? ~ : ~())\n",
" (~ ? ~() : (void)0, ~)\n",
p_macro_name(t, "TYPE", NULL),
type_var,
type_var,
p_internal_varname(t, p_str("init_type"))));
p_internal_varname(t, p_str("init_type")),
type_var));
output_var(out, "type",
p_str("GtkType"),
type_var);
@ -270,4 +296,14 @@ void output_def(PRoot* out, Def* d){
}
}
/*
void add_dep(PRoot* out, Id tag, PrimType* type){
pr_put(out, tag, type->module);
}
PNode* p_deps(Id tag){
return p_col(tag, p_dep, NULL);
}
*/

View File

@ -58,6 +58,8 @@ PNode* p_guard_end(const gchar *c);
PNode* p_c_ident(Id id);
PNode* p_c_macro(Id id);
PNode* p_prot_header(Module* m);
PNode* p_type_header(Module* m);
void output_func(PRoot* out,
@ -71,8 +73,11 @@ void output_func(PRoot* out,
void output_var(PRoot* out, Id tag, PNode* type, PNode* name);
void output_def(PRoot* out, Def* d);
void output_object(PRoot* out, ObjectDef* d);
void output_enum(PRoot* out, EnumDef* d);
void output_flags(PRoot* out, FlagsDef* d);
void output_object(PRoot* out, Def* d);
void output_enum(PRoot* out, Def* d);
void output_flags(PRoot* out, Def* d);
PNode* p_type_include(Module* m);
#endif

View File

@ -31,7 +31,7 @@ void output_enum_type_init(PRoot* out, EnumDef* e){
PrimType* t=DEF(e)->type;
output_func(out,
"type",
type_gtk_type,
NULL,
p_internal_varname(t, p_str("init_type")),
p_nil,
NULL,
@ -39,8 +39,7 @@ void output_enum_type_init(PRoot* out, EnumDef* e){
"~"
"\t\t{0, NULL, NULL}\n"
"\t};\n"
"\t~ = gtk_type_register_enum (\"~\", values);\n"
"\treturn ~;\n",
"\t~ = gtk_type_register_enum (\"~\", values);\n",
p_prf("%d", g_slist_length(e->alternatives)+1),
p_for(e->alternatives, p_enum_value, t),
p_internal_varname(t, p_str("type")),
@ -48,7 +47,8 @@ void output_enum_type_init(PRoot* out, EnumDef* e){
p_internal_varname(t, p_str("type"))));
}
void output_enum(PRoot* out, EnumDef* e){
void output_enum(PRoot* out, Def* d){
EnumDef* e = (EnumDef*)d;
output_enum_type_init(out, e);
pr_add(out, "type", p_enum_decl(e));
}

View File

@ -13,10 +13,9 @@ PNode* p_flags_member(Id id, FlagData* d){
}
PNode* p_flags_decl(FlagsDef* e){
FlagData d={
-1,
DEF(e)->type
};
FlagData d;
d.i = -1;
d.t = DEF(e)->type;
return p_fmt("typedef enum {\n"
"~"
"} ~;\n"
@ -49,8 +48,7 @@ void output_flags_type_init(PRoot* out, FlagsDef* e){
"~"
"\t\t{0, NULL, NULL}\n"
"\t};\n"
"\t~ = gtk_type_register_flags (\"~\", values);\n"
"\treturn ~;\n",
"\t~ = gtk_type_register_flags (\"~\", values);\n",
p_prf("%d", g_slist_length(e->flags)+1),
p_for(e->flags, p_flags_value, t),
p_internal_varname(t, p_str("type")),
@ -58,8 +56,9 @@ void output_flags_type_init(PRoot* out, FlagsDef* e){
p_internal_varname(t, p_str("type"))));
}
void output_flags(PRoot* out, FlagsDef* e){
pr_add(out, "type", p_flags_decl(e));
output_flags_type_init(out, e);
void output_flags(PRoot* out, Def* d){
FlagsDef* f = (FlagsDef*) d;
pr_add(out, "type", p_flags_decl(f));
output_flags_type_init(out, f);
}

View File

@ -130,6 +130,11 @@ void output_connector(PRoot* out, Method* m){
p_str(MEMBER(m)->name)));
}
PNode* p_param_marshtype(gpointer p){
Param* param=p;
return p_fmt(",\n\t\t~",
p_gtktype(&param->type));
}
void output_method(PRoot* out, Method* m){
@ -148,6 +153,7 @@ void output_method(PRoot* out, Method* m){
p_self_name(MEMBER(m)),
p_nil,
m->params);
switch(k){
SignalType* sig;
case METH_EMIT_PRE:
@ -155,10 +161,43 @@ void output_method(PRoot* out, Method* m){
case METH_EMIT_BOTH:
sig=sig_type(m);
output_var(out, NULL,
p_str("GtkSignalID"),
p_str("guint"),
p_signal_id(m));
o.names=FALSE;
o.types=TRUE;
pr_put(out, "class_init_head",
p_fmt("\textern void ~ (GtkObject*, GtkSignalFunc, "
"gpointer, GtkArg*);\n",
p_signal_demarshaller_name(sig)));
pr_put(out, "member_class_init",
p_fmt("\t~ =\n"
"\tgtk_signal_new(\"~\",\n"
"\t\tGTK_RUN_~,\n"
"\t\tobklass->type,\n"
"\t\tGTK_SIGNAL_OFFSET (~, ~),\n"
"\t\t~,\n"
"\t\t~,\n"
"\t\t~"
"~);\n"
"\tgtk_object_class_add_signals(obklass,\n"
"\t\t&~,\n"
"\t\t1);\n"
"\t}\n",
p_signal_id(m),
p_str(MEMBER(m)->name),
p_str(m->kind==METH_EMIT_PRE
?"FIRST"
:m->kind==METH_EMIT_POST
?"LAST"
:"BOTH"),
p_class_name(t),
name,
p_signal_demarshaller_name(sig),
p_gtktype(&m->ret_type),
p_prf("%d", g_slist_length(m->params)),
p_for(m->params, p_param_marshtype, p_nil),
p_signal_id(m)));
pr_add(out, "functions",
p_fmt("typedef ~ (*~)(~, gpointer);\n",
p_type(&m->ret_type),
@ -174,20 +213,22 @@ void output_method(PRoot* out, Method* m){
o.names=TRUE;
o.types=TRUE;
pr_add(out, "source_head",
p_fmt("static inline ~ ~ (~);\n",
p_fmt("static ~ ~_~_real (~);\n",
p_type(&m->ret_type),
p_real_varname(t, name),
p_c_ident(t->name),
name,
p_params(par, &o)));
o.types=FALSE;
dispatch=p_fmt("\t~ ~(~);\n",
dispatch=p_fmt("\t~~_~_real (~);\n",
m->ret_type.prim?
p_str("return "):
p_nil,
p_real_varname(t, name),
p_c_ident(t->name),
name,
p_params(par, &o));
break;
case METH_VIRTUAL:
dispatch=p_fmt("\t~((~*)((GtkObject*)~)->klass)->~(~);\n",
dispatch=p_fmt("\t~((~*)((GtkObject*) ~)->klass)->~ (~);\n",
m->ret_type.prim?
p_str("return "):
p_nil,
@ -213,7 +254,7 @@ void output_data_member(PRoot* out, DataMember* m){
PrimType* t=DEF(MEMBER(m)->my_class)->type;
PNode* name = p_c_ident(MEMBER(m)->name);
PNode* self = p_self_name(MEMBER(m));
switch(m->prot){
FunParams* par;
@ -262,6 +303,7 @@ void output_data_member(PRoot* out, DataMember* m){
}
/* fall through */
case DATA_READONLY:
pr_put(out, "func_depends", m->type.prim->module);
par=fparams("t", &MEMBER(m)->my_class->self_type[TRUE],
self,
p_nil);
@ -275,7 +317,9 @@ void output_data_member(PRoot* out, DataMember* m){
self,
name));
fparams_free(par);
/* fall through */
case DATA_PROTECTED:
pr_put(out, "prot_depends", m->type.prim->module);
}
}
@ -307,7 +351,7 @@ void output_object_type_init(PRoot* out, ObjectDef* o){
PNode* type_var=p_internal_varname(t, p_str("type"));
output_func(out,
"type",
type_gtk_type,
NULL,
p_internal_varname(t, p_str("init_type")),
p_nil,
NULL,
@ -322,8 +366,7 @@ void output_object_type_init(PRoot* out, ObjectDef* o){
"\t\tNULL,\n"
"\t};\n"
"\tif (!~)\n"
"\t\t~ = gtk_type_unique (~, &info);\n"
"\treturn ~;\n",
"\t\t~ = gtk_type_unique (~, &info);\n",
p_primtype(t),
p_primtype(t),
p_class_name(t),
@ -335,67 +378,12 @@ void output_object_type_init(PRoot* out, ObjectDef* o){
type_var));
}
PNode* p_param_marshtype(gpointer p){
Param* param=p;
return p_fmt(",\n\t\t~",
p_gtktype(&param->type));
}
PNode* p_member_class_init(gpointer m, gpointer o){
ObjectDef* ob=o;
Member* mem=m;
Method* meth;
SignalType* sig;
if(mem->membertype!=MEMBER_METHOD)
return p_nil;
meth=m;
sig=sig_type(meth);
switch(meth->kind){
case METH_EMIT_PRE:
case METH_EMIT_POST:
case METH_EMIT_BOTH:
return p_fmt("\t{\n"
"\textern void ~ (GtkObject*, GtkSignalFunc, "
"gpointer, GtkArg*);\n"
"\t~ =\n"
"\tgtk_signal_new(\"~\",\n"
"\t\tGTK_RUN_~,\n"
"\t\tobklass->type,\n"
"\t\tGTK_SIGNAL_OFFSET (~, ~),\n"
"\t\t~,\n"
"\t\t~,\n"
"\t\t~"
"~);\n"
"\tgtk_object_class_add_signals(obklass,\n"
"\t\t&~,\n"
"\t\t1);\n"
"\t}\n",
p_signal_demarshaller_name(sig),
p_signal_id(meth),
p_str(mem->name),
p_str(meth->kind==METH_EMIT_PRE
?"FIRST"
:meth->kind==METH_EMIT_POST
?"LAST"
:"BOTH"),
p_class_name(DEF(ob)->type),
p_c_ident(mem->name),
p_signal_demarshaller_name(sig),
p_gtktype(&meth->ret_type),
p_prf("%d", g_slist_length(meth->params)),
p_for(meth->params, p_param_marshtype, p_nil),
p_signal_id(meth));
break;
default:
return p_nil;
break;
}
sig_type_free(sig);
}
void output_object_init(PRoot* out, ObjectDef* o){
pr_add(out, "prot_deps",
p_col("prot_depends", p_type_include));
pr_add(out, "func_deps",
p_col("func_depends", p_type_include));
pr_add(out, "source_head",
p_fmt("static inline void ~ (~ ~);\n",
p_varname(DEF(o)->type, p_str("init_real")),
@ -424,15 +412,18 @@ void output_class_init(PRoot* out, ObjectDef* o){
p_fmt("~* klass",
p_class_name(DEF(o)->type)),
NULL,
p_fmt("\tGtkObjectClass* obklass = \n"
"\t\t(GtkObjectClass*) klass;\n"
p_fmt("\tGtkObjectClass* obklass = "
"(GtkObjectClass*) klass;\n"
"~"
"~"
"\t~ (klass);\n",
p_for(o->members, p_member_class_init, o),
p_col("class_init_head", NULL),
p_col("member_class_init", NULL),
p_varname(DEF(o)->type, p_str("class_init_real"))));
}
void output_object(PRoot* out, ObjectDef* o){
void output_object(PRoot* out, Def* d){
ObjectDef* o = (ObjectDef*)d;
output_object_type_init(out, o);
output_class_init(out, o);
output_object_init(out, o);

View File

@ -2,14 +2,13 @@
#include "gcg.h"
#define YYDEBUG 1
static Package* current_package;
static Module* current_module;
static Id current_header;
static ObjectDef* current_class;
static GSList* imports;
static Method* current_method;
static GSList* imports_list;
%}
%union {
@ -70,12 +69,15 @@ static GSList* imports_list;
%token T_DOUBLE
%token T_BOXED
%token T_SIGNAL
%token T_FOREIGN
%token T_PACKAGE
%token<id> T_IDENT
%token<id> T_HEADERNAME
%token<str> T_STRING
%type<id> ident
%type<id> headerdef
%type<fund_type> fundtype
%type<type> type
%type<type> typeorvoid
@ -108,28 +110,74 @@ start_symbol: deffile ;
deffile: declarations definitions;
declarations: /* empty */ | declarations modulescope;
declarations: /* empty */ | declarations package;
definitions: current_module_def deflist;
deflist: /* empty */ | deflist def {
put_def($2);
};
} | deflist import;
import: T_IMPORT ident T_END {
imports=g_slist_prepend(imports, (gpointer)($2));
import: T_IMPORT importlist T_END;
importlist: ident {
Package* p = get_pkg($1);
if(!p)
g_error("Attempt to import unknown package %s", $1);
imports_list = g_slist_prepend(imports_list, p);
} | importlist T_COMMA ident {
Package* p = get_pkg($3);
if(!p)
g_error("Attempt to import unknown package %s", $3);
imports_list = g_slist_prepend(imports_list, p);
}
modulescope: T_MODULE ident T_OPEN_B {
current_module=get_mod($2);
} decllist T_CLOSE_B {
current_module=NULL;
} T_END;
current_module_def: T_MODULE ident T_END {
current_module=get_mod($2);
package: T_PACKAGE ident T_OPEN_B {
Package* p = get_pkg($2);
if(!p){
p = g_new(Package, 1);
p->name = $2;
p->type_hash = g_hash_table_new(NULL, NULL);
p->mod_hash = g_hash_table_new(NULL, NULL);
put_pkg(p);
}
current_package = p;
} modulelist T_CLOSE_B {
current_package = NULL;
};
current_module_def: T_MODULE ident T_SCOPE ident T_END {
Package* p = get_pkg($2);
Module* m;
if(!p)
g_error("Unknown package %s", $2);
m = get_mod(p, $4);
if(!m)
g_error("Unknown module %s.%s", $2, $4);
current_module = m;
}
modulelist: /* empty */ | modulelist module;
headerdef: /* empty */ {
$$ = NULL;
}| T_HEADERNAME;
module: T_MODULE ident headerdef T_OPEN_B {
Module* m = get_mod(current_package, $2);
if(!m){
m = g_new(Module, 1);
m->package = current_package;
m->name = $2;
m->header = $3;
put_mod(m);
}
current_module = m;
} decllist T_CLOSE_B;
decllist: /* empty */ | decllist decl;
decl: simpledecl ;/* | classdecl | opaquedecl | protclassdecl;*/
@ -148,9 +196,12 @@ fundtype: T_INT {
$$ = TYPE_FLAGS;
}
simpledecl: fundtype primtype T_END {
g_assert($2->kind==TYPE_INVALID);
$2->kind = $1;
simpledecl: fundtype ident T_END {
PrimType* t = g_new(PrimType, 1);
t->module = current_module;
t->name = $2;
t->kind = $1;
put_type(t);
};
semitype: const_def primtype {
@ -181,9 +232,26 @@ typeorvoid: type | T_VOID {
primtype: ident T_SCOPE ident {
$$ = get_type($1, $3);
Package* p=get_pkg($1);
PrimType* t;
if(!p)
g_error("Unknown package %s!", $1);
t = get_type(p, $3);
if(!t)
g_error("Unknown type %s:%s", $1, $3);
$$ = t;
} | ident {
$$ = get_type(current_module->name, $1);
Package* p = current_module->package;
PrimType* t;
GSList* l = imports_list;
t = get_type(p, $1);
while(l && !t){
t = get_type(l->data, $1);
l = l->next;
}
if(!t)
g_error("Couldn't find type %s in import list", $1);
$$ = t;
};
paramlist: /* empty */ {
@ -271,22 +339,22 @@ idlist: ident {
def: classdef | enumdef | flagsdef;
enumdef: T_ENUM primtype T_OPEN_B idlist T_CLOSE_B docstring T_END {
enumdef: T_ENUM primtype docstring T_OPEN_B idlist T_CLOSE_B {
EnumDef* d=g_new(EnumDef, 1);
g_assert($2->kind==TYPE_ENUM);
d->alternatives = $4;
d->alternatives = $5;
$$=DEF(d);
$$->type=$2;
$$->doc=$6;
$$->doc=$3;
};
flagsdef: T_FLAGS primtype T_OPEN_B idlist T_CLOSE_B docstring T_END {
flagsdef: T_FLAGS primtype docstring T_OPEN_B idlist T_CLOSE_B T_END {
FlagsDef* d=g_new(FlagsDef, 1);
g_assert($2->kind==TYPE_ENUM);
d->flags = $4;
d->flags = $5;
$$=DEF(d);
$$->type=$2;
$$->doc=$6;
$$->doc=$3;
};
parent: /* empty */{
@ -298,9 +366,14 @@ parent: /* empty */{
classdef: T_CLASS primtype parent docstring T_OPEN_B {
g_assert($2->kind==TYPE_OBJECT);
g_assert(!$3 || $3->kind==TYPE_OBJECT);
g_assert($2->module == current_module);
current_class=g_new(ObjectDef, 1);
} classbody T_CLOSE_B T_END {
Type t={FALSE, 1, TRUE, $2};
} classbody T_CLOSE_B {
Type t;
t.is_const = FALSE;
t.indirection = 1;
t.notnull = TRUE;
t.prim = $2;
current_class->self_type[0]=t;
t.is_const=TRUE;
current_class->self_type[1]=t;

View File

@ -2,36 +2,67 @@
#include <stdio.h>
#include <stdarg.h>
const gconstpointer p_no_data = &p_no_data;
static const gconstpointer p_node_magic_tag = &p_node_magic_tag;
#define BE_NODE(x) (g_assert((x) && ((PNode*)(x))->magic == &p_node_magic_tag))
#define BE_NODE(x) g_assert((x) && ((PNode*)(x))->magic == &p_node_magic_tag)
static GMemChunk* p_node_chunk;
static GList* p_float_list;
static GHashTable* p_str_hash;
typedef enum{
NODE_NIL,
NODE_DATA,
NODE_COLLECT
} PNodeType;
typedef struct{
gchar* str;
PNode* node;
} PBlock;
typedef struct _PRNode{
GQuark tag;
PNode* node;
} PRNode;
struct _PRoot{
GData* data;
GList* nodes;
};
struct _PNode{
gconstpointer magic;
guint ref_count;
GList* float_link;
const gchar* str;
GSList* children;
PNodeType type;
union {
struct {
gint nblocks;
PBlock* blocks;
} b;
struct {
PNodeCreateFunc func;
GQuark tag;
} c;
} u;
};
static PNode p_nil_node = {
&p_node_magic_tag,
-1,
NULL,
NULL,
NULL
NODE_NIL,
{{0,NULL}}
};
PNode* p_nil = &p_nil_node;
static PNode* p_make(void){
static PNode* p_make(PNodeType type){
PNode* node;
if(!p_node_chunk)
p_node_chunk = g_mem_chunk_create(PNode, 1024,
@ -41,8 +72,7 @@ static PNode* p_make(void){
node->ref_count = 0;
node->magic = &p_node_magic_tag;
node->float_link = p_float_list = g_list_prepend(p_float_list, node);
node->str = NULL;
node->children = NULL;
node->type = type;
return node;
}
@ -65,162 +95,178 @@ void p_unref(PNode* node){
node->ref_count--;
if(node->ref_count>0)
return;
else{
GSList* l;
if(node->children){
for(l = node->children;l;l = l->next)
p_unref(l->data);
g_slist_free(node->children);
} else
g_hash_table_remove(p_str_hash, node->str);
g_free((gpointer)node->str);
g_mem_chunk_free(p_node_chunk, node);
switch(node->type){
case NODE_DATA:{
PBlock* bl = node->u.b.blocks;
gint i=node->u.b.nblocks;
while(i--){
g_free(bl[i].str);
p_unref(bl[i].node);
}
g_free(bl);
break;
}
case NODE_NIL:
break;
case NODE_COLLECT:
break;
}
g_mem_chunk_free(p_node_chunk, node);
}
typedef struct{
FILE* f;
PRoot* p;
} PWrite;
typedef struct{
PWrite* w;
PNode* n;
} PCollect;
static void p_write(PNode* node, PWrite* w);
void cb_pwrite(gpointer key, gpointer value, gpointer data){
PCollect* c = data;
PNodeCreateFunc func = c->n->u.c.func;
(void)key;
if(func)
p_write(func(value), c->w);
else
p_write(value, c->w);
}
static void p_write(PNode* node, PWrite* w){
BE_NODE(node);
switch(node->type){
case NODE_DATA:{
gint i = 0, n = node->u.b.nblocks;
PBlock* bl = node->u.b.blocks;
for(i = 0; i < n; i++){
if(bl[i].str)
fputs(bl[i].str, w->f);
p_write(bl[i].node, w);
}
break;
}
case NODE_NIL:
break;
case NODE_COLLECT:{
GHashTable* h = g_datalist_id_get_data(&w->p->data,
node->u.c.tag);
PCollect c;
c.w = w;
c.n = node;
if(!h)
break;
g_hash_table_foreach(h, cb_pwrite, &c);
break;
}
}
}
void p_write(PNode* node, FILE* f){
GSList* l;
BE_NODE(node);
if(node==p_nil)
return;
l = node->children;
if(l){
const gchar* c = node->str;
if(c)
while(*c){
gint i = 0;
while(c[i] && c[i] != '~')
i++;
fwrite(c, i, 1, f);
c += i;
if(*c == '~'){
c++;
g_assert(l);
p_write(l->data, f);
l = l->next;
}
}
else
do{
p_write(l->data, f);
}while((l=l->next));
}else if(node->str)
fputs(node->str, f);
static PNode* p_simple_string(gchar* str){
PNode* n = p_make(NODE_DATA);
n->u.b.nblocks = 1;
n->u.b.blocks = g_new(PBlock, 1);
n->u.b.blocks[0].str = str;
n->u.b.blocks[0].node = p_nil;
return n;
}
void p_traverse(PNode* node, PNodeTraverseFunc func, gpointer user_data){
GSList* l;
BE_NODE(node);
func(node, user_data);
for(l=node->children;l;l=l->next)
p_traverse(l->data, func, user_data);
}
PNode* p_str(const gchar* str){
PNode* n;
if(!p_str_hash)
p_str_hash = g_hash_table_new(g_str_hash, g_str_equal);
n = g_hash_table_lookup(p_str_hash, str);
if(!n){
n = p_make();
n->str = g_strdup(str);
g_hash_table_insert(p_str_hash, n->str, n);
}
return n;
if(n)
return n;
else
return p_simple_string(g_strdup(str));
}
PNode* p_prf(const gchar* format, ...){
PNode* n = p_make();
PNode* n;
va_list args;
va_start(args, format);
n->str = g_strdup_vprintf (format, args);
n = p_simple_string(g_strdup_vprintf (format, args));
va_end(args);
return n;
}
PNode* p_fmt(const gchar* f, ...){
va_list args;
gchar* b = f;
PNode* n;
GSList* l = NULL;
const gchar* b;
PNode* n = p_make(NODE_DATA);
gint i;
PBlock* bl;
va_start(args, f);
g_assert(f);
while(*f){
while(*f && *f != '~')
f++;
if(*f == '~'){
PNode* p;
for(b = f, i = 0; *b; b++)
if(*b == '~')
i++;
if(b!=f && b[-1] != '~')
i++;
bl = g_new(PBlock, i);
n->u.b.blocks = bl;
n->u.b.nblocks = i;
for(b = f, i = 0; *b; i++){
gint idx=0;
PNode* p = p_nil;
while(b[idx] && b[idx] != '~')
idx++;
bl[i].str = g_strndup(b, idx);
if(b[idx] == '~'){
p = va_arg(args, PNode*);
BE_NODE(p);
if(p!=p_nil)
p_ref(p);
l = g_slist_prepend(l, p);
f++;
p_ref(p);
idx++;
}
bl[i].node = p;
b = &b[idx];
}
if(!l)
return p_str(f);
n = p_make();
n->str = g_strdup(b);
n->children = g_slist_reverse(l);
return n;
}
PNode* p_lst(PNode* n, ...){
va_list args;
GSList* l = NULL;
PNode* node;
g_assert(n);
va_start(args, n);
while(n){
BE_NODE(n);
if(n!=p_nil){
p_ref(n);
l = g_slist_prepend(l, n);
}
n = va_arg(args, PNode*);
}
node = p_make();
node->children = g_slist_reverse(l);
return node;
}
PNode* p_for(GSList* l, PNodeCreateFunc func, gpointer user_data){
PNode* n = p_make();
GSList* lst = NULL;
n->str = NULL;
PNode* p_for(GSList* lst, PNodeCreateFunc func, gpointer user_data){
PNode* n = p_make(NODE_DATA);
GSList* l = lst;
gint i = g_slist_length(l);
n->u.b.nblocks = i;
n->u.b.blocks = g_new(PBlock, i);
i = 0;
while(l){
PNode* p;
if(user_data==p_nil)
p=func(l->data);
if(user_data == p_nil)
p = func(l->data);
else
p=func(l->data, user_data);
p = func(l->data, user_data);
BE_NODE(p);
if(p!=p_nil){
p_ref(p);
lst=g_slist_prepend(lst, p);
}
l=l->next;
p_ref(p);
n->u.b.blocks[i].str = NULL;
n->u.b.blocks[i++].node = p;
l = l->next;
}
n->children=g_slist_reverse(lst);
return n;
}
typedef struct _PRNode{
GQuark tag;
PNode* node;
} PRNode;
struct _PRoot{
GList* nodes;
};
PNode* p_col(const gchar* tag, PNodeCreateFunc func){
PNode* n = p_make(NODE_COLLECT);
n->u.c.func = func;
n->u.c.tag = g_quark_from_string(tag);
return n;
}
PRoot* pr_new(void){
PRoot* pr = g_new(PRoot, 1);
pr->nodes = NULL;
g_datalist_init(&pr->data);
return pr;
}
@ -237,27 +283,49 @@ void pr_add(PRoot* pr, const gchar* tag, PNode* node){
p_ref(node);
}
void pr_write(PRoot* pr, FILE* stream, const gchar** tags, gint n){
GList* l;
GQuark* quarks;
gint i;
void pr_put(PRoot* pr, const gchar* tag, gpointer datum){
GHashTable* h = g_datalist_get_data(&pr->data, tag);
if(!h){
h = g_hash_table_new(NULL, NULL);
g_datalist_set_data(&pr->data, tag, h);
}
quarks=g_new(GQuark, n);
for(i=0;i<n;i++)
quarks[i]=g_quark_from_string(tags[i]);
g_hash_table_insert(h, datum, datum);
}
void pr_write(PRoot* pr, FILE* stream, const gchar* tag){
GList* l;
GQuark q;
PWrite w;
g_assert(pr);
w.p = pr;
w.f = stream;
q = g_quark_from_string(tag);
for(l=g_list_last(pr->nodes);l;l=l->prev){
PRNode* node = l->data;
for(i=0;i<n;i++)
if(node->tag==quarks[i])
break;
if(i==n)
continue;
p_write(node->node, stream);
if(node->tag == q)
p_write(node->node, &w);
}
}
gchar* pr_to_str(PRoot* pr, const gchar* tag){
FILE* f = tmpfile();
glong len;
gchar* buf;
pr_write(pr, f, tag);
len = ftell(f);
rewind(f);
buf = g_new(gchar, len+1);
fread(buf, len, 1, f);
buf[len]='\0';
fclose(f);
return buf;
}
void pr_free(PRoot* pr){
GList* l;
for(l=pr->nodes;l;l = l->next){

View File

@ -13,19 +13,20 @@ typedef PNode* (*PNodeCreateFunc) ();
void p_ref(PNode* node);
void p_unref(PNode* node);
void p_write(PNode* node, FILE* f);
PNode* p_str(const gchar* str);
PNode* p_qrk(const gchar* str);
PNode* p_prf(const gchar* format, ...) G_GNUC_PRINTF(1, 2);
PNode* p_fmt(const gchar* f, ...);
PNode* p_lst(PNode* n, ...);
PNode* p_for(GSList* l, PNodeCreateFunc func, gpointer user_data);
void p_traverse(PNode* node, PNodeTraverseFunc func, gpointer user_data);
PNode* p_col(const gchar* tag, PNodeCreateFunc func);
PRoot* pr_new(void);
void pr_add(PRoot* root, const gchar* tag, PNode* node);
void pr_write(PRoot* pr, FILE* stream, const gchar** tags, gint n);
void pr_put(PRoot* pr, const gchar* tag, gpointer datum);
void pr_write(PRoot* pr, FILE* stream, const gchar* tag);
void pr_free(PRoot* root);
gchar* pr_to_str(PRoot* pr, const gchar* tags);
#endif