It actually runs now, with a zillion caveats, but anyway..

Still have to do lotsa things for serious use..
This commit is contained in:
Lauri Alanko 1998-11-20 23:21:40 +00:00
parent 51b4b0966e
commit d74bf3623e
26 changed files with 506 additions and 244 deletions

View File

@ -1,3 +1,8 @@
1998-11-21 Lauri Alanko <la@iki.fi>
* It actually runs now, with a zillion caveats, but anyway..
Still have to do lotsa things for serious use..
1998-11-20 Lauri Alanko <la@iki.fi>
* Again modified the formatting stuff. Some preliminary header

View File

@ -1,9 +1,11 @@
noinst_PROGRAMS = gcg
CPP=cpp -nostdinc -I /usr/share/gcg -I /usr/local/share/gcg -I .
CFLAGS=-g -Wall -W -DCPP="$(CPP)" -ansi -pedantic
CFLAGS=-g -Wall -W "-DCPP=\"$(CPP)\""
INCLUDES = @GLIB_CFLAGS@
YFLAGS = -d -v 2>/dev/null
YFLAGS = -d -v
LFLAGS = -d
LIBS = @GLIB_LIBS@
lexer.c: $(srcdir)/lexer.l

View File

@ -2,7 +2,8 @@ AC_INIT(gcg.c)
AM_INIT_AUTOMAKE(gcg, 0.1)
AC_PROG_CC
AC_PROG_CPP
AC_PROG_RANLIB
AC_PROG_YACC
AM_PROG_LEX
AM_PATH_GLIB(1.0.0,,AC_ERROR(need at least Glib version 1.0))
AC_OUTPUT(Makefile)
AC_OUTPUT([Makefile ex/Makefile])

View File

@ -10,12 +10,16 @@ void init_db(void){
}
PrimType* get_type(Package* pkg, Id name){
return g_hash_table_lookup(pkg->type_hash, name);
if(pkg)
return g_hash_table_lookup(pkg->type_hash, name);
else
return NULL;
}
void put_type(PrimType* t){
g_hash_table_insert(t->module->package->type_hash,
(gpointer)t->name, t);
if(t->module && t->module->package)
g_hash_table_insert(t->module->package->type_hash,
(gpointer)t->name, t);
}
void put_def(Def* d){
@ -31,11 +35,15 @@ void put_pkg(Package* pkg){
}
Module* get_mod(Package* pkg, Id modname){
return g_hash_table_lookup(pkg->mod_hash, modname);
if(pkg)
return g_hash_table_lookup(pkg->mod_hash, modname);
else
return NULL;
}
void put_mod(Module* m){
g_hash_table_insert(m->package->mod_hash, (gpointer)m->name, m);
if(m->package)
g_hash_table_insert(m->package->mod_hash, (gpointer)m->name, m);
}
void foreach_def(DefFunc f, gpointer user_data){

22
tools/gcg/ex/Makefile.am Normal file
View File

@ -0,0 +1,22 @@
noinst_LIBRARIES = libgcgexample.a
CFLAGS=-g -Wall -W -I..
SUFFIXES = .gc .gh
EXTRA_DIST = stream.gh ostream.gc fileostream.gc
BUILT_SOURCES = \
ostream_s.c ostream.h ostream_t.h ostream_p.h \
file_ostream_s.c file_ostream.h file_ostream_t.h file_ostream_p.h
DEFS = ostream_s.c file_ostream_s.c
$(DEFS): %_s.c: %.gc
../gcg -o $@ -I ../gh $<
libgcgexample_a_SOURCES = \
ostream_s.c file_ostream_s.c

1
tools/gcg/ex/README Normal file
View File

@ -0,0 +1 @@
This is just a bunch of miscellaneous test/example classes.

View File

@ -0,0 +1,24 @@
#include <stdio.h>
static void ex_file_ostream_init_real(ExFileOstream* str){
str->file = NULL;
}
static void put_char(ExOstream* s, gchar c){
ExFileOstream* str = EX_FILE_OSTREAM(s);
fputc(c, str->file);
}
static void ex_file_ostream_class_init_real(ExFileOstreamClass* klass){
((ExOstreamClass*)klass)->putchar = put_char;
}
static ExFileOstream* file_ostream_open_real(gchar* filename){
ExFileOstream* str;
FILE* f = fopen(filename, "w+");
if(!f)
return NULL;
str = gtk_type_new(EX_TYPE_FILE_OSTREAM);
str->file = f;
return str;
}

View File

@ -0,0 +1,15 @@
#include "stream.gh"
package{
module <stdio.h> {
foreign FILE;
}
}
module Ex.FileOstream;
class FileOstream : Ostream{
.FILE* file;
public static FileOstream* open(g.char* filename);
}

16
tools/gcg/ex/ostream.c Normal file
View File

@ -0,0 +1,16 @@
/* Aye, _mondo_ slow default method.. */
static void putstring(ExOstream* str, gchar* string){
gint i;
for(i = 0; string[i]; i++)
ex_ostream_putchar(str, string[i]);
}
static void ex_ostream_init_real(ExOstream* str){
}
static void ex_ostream_class_init_real(ExOstreamClass* klass){
klass->putstring = putstring;
}

12
tools/gcg/ex/ostream.gc Normal file
View File

@ -0,0 +1,12 @@
#include <stream.gh>
module Ex.Ostream;
import g;
class Ostream {
public virtual void putchar (char c);
public virtual void putstring (char* str);
public virtual void flush ();
public virtual void close ();
}

14
tools/gcg/ex/stream.gh Normal file
View File

@ -0,0 +1,14 @@
#include <gcg.gh>
package Ex {
module Ostream{
class Ostream;
}
module FileOstream{
class FileOstream;
}
module StringOstream{
class StringOstream;
}
}

View File

@ -1,10 +1,8 @@
#include "gcg.h"
#include "parser.h"
#include <stdio.h>
#include <glib.h>
#define __USE_POSIX2
#include <string.h>
#include <errno.h>
#include "gcg.h"
#include "parse.h"
#include <unistd.h>
#include "output.h"
@ -12,41 +10,36 @@
#define CPP "cpp"
#endif
Id header_root = "..";
Id source_name = NULL;
Id impl_name = NULL;
Type* type_gtk_type;
Id func_hdr_name;
Id type_hdr_name;
Id prot_hdr_name;
Id source_name;
Id impl_name;
extern int yydebug;
extern FILE* yyin;
extern int yyparse(void);
GString* cpp_cmd;
void get_options(int argc, char* argv[]){
gint x=0;
yydebug = yy_flex_debug = FALSE;
do{
x=getopt(argc, argv, "f:t:p:s:i:d");
x=getopt(argc, argv, "D:i:dI:o:");
switch(x){
case 'f':
func_hdr_name=optarg;
case 'D':
header_root=optarg;
break;
case 't':
type_hdr_name=optarg;
break;
case 'p':
prot_hdr_name=optarg;
break;
case 's':
source_name=optarg;
case 'I':
g_string_append(cpp_cmd, " -I ");
g_string_append(cpp_cmd, optarg);
break;
case 'i':
impl_name=optarg;
break;
case 'd':
yydebug=1;
if(!yydebug)
yydebug = TRUE;
else
yy_flex_debug = TRUE;
break;
case 'o':
source_name = optarg;
break;
case '?':
case ':':
@ -59,31 +52,102 @@ void output_cb(Def* def, gpointer out){
output_def(out, def);
}
void open_out(PNode*(*func)(Module*),
Id suffix, PNode* n, PRoot* out){
GString* s = g_string_new(header_root);
gchar* str;
PNode* guard;
FILE* f;
g_string_append(s, "/");
str = p_to_str(func(current_module), NULL);
g_string_append(s, str);
g_free(str);
f = fopen(s->str, "w+");
if(!f)
g_error("Unable to open file %s: %s",
s->str,
strerror(errno));
g_string_free(s, TRUE);
guard=p_fmt("_g_~_~_~",
p_c_ident(current_module->package->name),
p_c_ident(current_module->name),
p_str(suffix));
p_write(p_fmt("#ifndef ~\n"
"#define ~\n"
"~"
"#endif /* ~ */\n",
guard,
guard,
n,
guard),
f, out);
fclose(f);
}
int main(int argc, char* argv[]){
/* target=stdout;*/
PRoot* out=pr_new();
FILE* f;
init_db();
cpp_cmd = g_string_new(CPP);
yydebug=0;
get_options(argc, argv);
yyin=fopen(argv[optind], "r");
g_string_append(cpp_cmd, " ");
g_string_append(cpp_cmd, argv[optind]);
yyin=popen(cpp_cmd->str, "r");
/*yyin=fopen(argv[optind], "r");*/
g_assert(yyin);
yyparse();
if(!impl_name)
impl_name = p_to_str(p_fmt("~.c",
p_c_ident(current_module->name)),
NULL);
if(!source_name)
source_name = p_to_str(p_fmt("~_s.c",
p_c_ident(current_module->name)),
NULL);
foreach_def(output_cb, out);
f=fopen(type_hdr_name, "w+");
pr_write(out, f, "type");
f=fopen(source_name, "w+");
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, "func_deps");
pr_write(out, f, "functions");
f=fopen(prot_hdr_name, "w+");
pr_write(out, f, "prot_deps");
pr_write(out, f, "protected");
if(!f)
g_error("Unable to open file %s: %s",
source_name, strerror(errno));
p_write(p_fmt("~~~"
"#include \"~\"\n",
p_col("source_prot_depends", p_prot_include),
p_col("source_head", NULL),
p_col("source", NULL),
p_str(impl_name)),
f, out);
fclose(f);
open_out(p_type_header, "type",
p_fmt("#include <gtk/gtktypeutils.h>\n"
"~",
p_col("type", NULL)),
out);
open_out(p_func_header, "funcs",
p_fmt("~~~",
p_col("func_parent_depends", p_func_include),
p_col("func_depends", p_type_include),
p_col("functions", NULL)),
out);
open_out(p_prot_header, "prot",
p_fmt("~~~",
p_col("prot_parent_depends", p_prot_include),
p_col("prot_depends", p_type_include),
p_col("protected", NULL)),
out);
return 0;
}

View File

@ -34,11 +34,14 @@ typedef enum{
TYPE_ENUM,
TYPE_FLAGS,
TYPE_FOREIGN,
TYPE_OBJECT
TYPE_OBJECT,
TYPE_BOXED,
TYPE_CHAR
} TypeKind;
struct _Package {
Id name;
Id headerbase;
GHashTable* type_hash;
GHashTable* mod_hash;
};

11
tools/gcg/gh/gcg.gh Normal file
View File

@ -0,0 +1,11 @@
package Gtk{
module <gtk/gtksignal.h>{
class Object;
}
}
#include <glib.gh>
root Gtk.Object;

30
tools/gcg/gh/glib.gh Normal file
View File

@ -0,0 +1,30 @@
package g {
module <glib.h> {
integer int;
integer uint;
integer boolean;
character char;
character uchar;
}
}
package G {
module <glib.h> {
boxed List;
boxed SList;
boxed HashTable;
boxed String;
boxed Array;
boxed Cache;
boxed Data;
boxed Node;
boxed Scanner;
boxed ScannerConfig;
boxed Relation;
boxed MemChunk;
boxed Hook;
foreign Func;
foreign HashFunc;
foreign HFunc;
}
}

View File

@ -1,43 +0,0 @@
// this is just a simple test input file
#include <gimp.gh>
module Gimp.Image;
import g;
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 int width;
read-only int height;
int num-cols;
read-only BaseType base-type;
read-write int foobar;
read-write Layer& active-layer;
read-write Layer* floating-sel;
public static Image* new(g.int width,
g.int height,
BaseType base-type);
public void add-layer(Layer* l);
public static g.int foo-1(Layer* x);
public direct g.int foo-2(Layer* x);
public abstract void foo-3(g.int x);
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,
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

@ -2,8 +2,9 @@
%option yylineno
%{
#include "gcg.h"
#include "gcg.h"
#include "parser.h"
#include "parse.h"
%}
@ -14,9 +15,10 @@ comment \/\/[^\n]*\n
string \"(([^\"]*)|\\\"|\\\\)*\"
preproc ^#.*\n
%%
class return T_CLASS;
public return T_PUBLIC;
static return T_STATIC;
protected return T_PROTECTED;
@ -27,7 +29,7 @@ read-only return T_READ_ONLY;
read-write return T_READ_WRITE;
private return T_PRIVATE;
const return T_CONST;
abstract return T_ABSTRACT;
virtual return T_ABSTRACT;
direct return T_DIRECT;
type return T_TYPE;
attribute return T_ATTRIBUTE;
@ -36,15 +38,17 @@ import return T_IMPORT;
header return T_HEADER;
opaque return T_OPAQUE;
package return T_PACKAGE;
void return T_VOID;
root return T_ROOT;
class return T_CLASS;
enum return T_ENUM;
flags return T_FLAGS;
@int return T_INT;
real return T_DOUBLE;
integer return T_INT;
double return T_DOUBLE;
boxed return T_BOXED;
foreign return T_FOREIGN;
character return T_CHAR;
{ident} {
yylval.id=g_quark_to_string(g_quark_from_string(yytext));

View File

@ -112,13 +112,22 @@ PNode* p_gtktype(Type* t){
case TYPE_ENUM:
case TYPE_FLAGS:
return p_macro_name(t->prim, "TYPE", NULL);
case TYPE_CHAR:
return p_str("GTK_TYPE_CHAR");
case TYPE_FOREIGN:
g_error("Cannot marshall foreign type %s.%s!",
t->prim->module->package->name,
t->prim->name);
return NULL;
default:
g_assert_not_reached();
return p_str("GTK_TYPE_NONE");
g_error("Cannot marshall type by value: %s.%s",
t->prim->module->package->name,
t->prim->name);
return NULL;
}
}else if(t->indirection==1
&& t->prim
&& (t->prim->kind==TYPE_FOREIGN
&& (t->prim->kind==TYPE_BOXED
|| t->prim->kind==TYPE_OBJECT))
return p_macro_name(t->prim, "TYPE", NULL);
else

View File

@ -5,42 +5,41 @@
PNode* p_c_ident(Id id){
PNode* n;
gchar* c;
gchar* s;
c=s=g_strdup(id);
while(*c){
*c=tolower(*c);
if(!isalnum(*c))
*c='_';
c++;
gint i = 0;
GString* s = g_string_new(NULL);
for(i = 0; id[i]; i++){
if(!isalnum(id[i]) || (i && isupper(id[i])))
g_string_append_c(s, '_');
if(isalnum(id[i]))
g_string_append_c(s, tolower(id[i]));
}
n=p_str(s);
g_free(s);
n = p_str(s->str);
g_string_free(s, TRUE);
return n;
}
PNode* p_c_macro(Id id){
PNode* n;
gchar* c;
gchar* s;
c=s=g_strdup(id);
while(*c){
*c=toupper(*c);
if(!isalnum(*c))
*c='_';
c++;
gint i = 0;
GString* s = g_string_new(NULL);
for(i = 0; id[i]; i++){
if(!isalnum(id[i]) || (i && isupper(id[i])))
g_string_append_c(s, '_');
if(isalnum(id[i]))
g_string_append_c(s, toupper(id[i]));
}
n=p_str(s);
g_free(s);
n = p_str(s->str);
g_string_free(s, TRUE);
return n;
}
PNode* p_param(FunParams* p, ParamOptions* opt){
return p_fmt("~~~~",
opt->first ? p_nil : p_str(", "),
return p_fmt("~~~~~~",
opt->first ? p_nil : p_str(","),
!opt->first && !opt->types ? p_str(" ") : p_nil,
opt->types ? p_str("\n\t") : p_nil,
opt->types ? p_type(&p->type) : p_nil,
opt->types && opt->names ? p_str(" ") : p_nil,
opt->names ? p->name : p_nil);
@ -51,7 +50,9 @@ PNode* p_prot_header(Module* m){
return p_str(m->header);
else
return p_fmt("~/~_p.h",
p_c_ident(m->package->name),
m->package->headerbase
? p_str(m->package->headerbase)
: p_c_ident(m->package->name),
p_c_ident(m->name));
}
@ -60,7 +61,20 @@ PNode* p_type_header(Module* m){
return p_str(m->header);
else
return p_fmt("~/~_t.h",
p_c_ident(m->package->name),
m->package->headerbase
? p_str(m->package->headerbase)
: p_c_ident(m->package->name),
p_c_ident(m->name));
}
PNode* p_func_header(Module* m){
if(m->header)
return p_str(m->header);
else
return p_fmt("~/~.h",
m->package->headerbase
? p_str(m->package->headerbase)
: p_c_ident(m->package->name),
p_c_ident(m->name));
}
@ -69,6 +83,17 @@ PNode* p_type_include(Module* m){
p_type_header(m));
}
PNode* p_prot_include(Module* m){
return p_fmt("#include <~>\n",
p_prot_header(m));
}
PNode* p_func_include(Module* m){
return p_fmt("#include <~>\n",
p_func_header(m));
}
PNode* p_params(FunParams* args, ParamOptions* opt){
ParamOptions o=*opt;
PNode* n=p_nil;
@ -155,21 +180,21 @@ PNode* p_type_guard(Type* t, PNode* var){
((t->indirection==1 && p->kind == TYPE_OBJECT)
? (t->notnull
? p_fmt("\tg_assert (~(~));\n",
p_macro_name(p, "IS", NULL),
p_macro_name(p, "is", NULL),
var)
: p_fmt("\tg_assert (!~ || ~(~));\n",
var,
p_macro_name(p, "IS", NULL),
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_macro_name(p, NULL, "last"))
: ((p->kind == TYPE_FLAGS)
? p_fmt("\tg_assert ((~ << 1) < ~);\n",
var,
p_macro_name(p, NULL, "LAST"))
p_macro_name(p, NULL, "last"))
: p_nil))
: p_nil)));
}
@ -199,7 +224,7 @@ PNode* p_prototype(Type* rettype, PNode* name,
}
void output_var_alias(PRoot* out, PrimType* t, PNode* basename){
pr_add(out, "import_alias",
pr_put(out, "import_alias",
p_fmt("#define ~ ~_~\n",
basename,
p_c_ident(t->module->package->name),
@ -207,7 +232,7 @@ void output_var_alias(PRoot* out, PrimType* t, PNode* basename){
}
void output_type_alias(PRoot* out, PrimType* t, PNode* basename){
pr_add(out, "import_alias",
pr_put(out, "import_alias",
p_fmt("typedef ~~ ~;\n",
p_str(t->module->package->name),
basename,
@ -222,13 +247,13 @@ void output_func(PRoot* out,
PNode* args1,
FunParams* args2,
PNode* body){
pr_add(out, tag ? tag : "source_head",
pr_put(out, tag ? tag : "source_head",
p_fmt("~~;\n",
tag
? p_nil
: p_str("static "),
p_prototype(rettype, name, args1, args2)));
pr_add(out, "source",
pr_put(out, "source",
p_fmt("~~{\n"
"~"
"~"
@ -252,11 +277,11 @@ PNode* p_macro_name(PrimType* t, Id mid, Id post){
void output_var(PRoot* out, Id tag, PNode* type, PNode* name){
if(tag)
pr_add(out, tag,
pr_put(out, tag,
p_fmt("extern ~ ~;\n",
type,
name));
pr_add(out, "source_head",
pr_put(out, "source_head",
p_fmt("~~ ~;\n",
tag?p_nil:p_str("static "),
type,
@ -268,13 +293,13 @@ void output_def(PRoot* out, Def* d){
PNode* type_var=p_internal_varname(t, p_str("type"));
/* GTK_TYPE_FOO macro */
pr_add(out, "type", p_str("\n\n"));
pr_add(out, "source", p_str("\n"));
pr_add(out, "protected", p_str("\n\n"));
pr_add(out, "source_head", p_str("\n"));
pr_add(out, "type", p_fmt("#define ~ \\\n"
pr_put(out, "type", p_str("\n\n"));
pr_put(out, "source", p_str("\n"));
pr_put(out, "protected", p_str("\n\n"));
pr_put(out, "source_head", p_str("\n"));
pr_put(out, "type", p_fmt("#define ~ \\\n"
" (~ ? ~() : (void)0, ~)\n",
p_macro_name(t, "TYPE", NULL),
p_macro_name(t, "type", NULL),
type_var,
p_internal_varname(t, p_str("init_type")),
type_var));

View File

@ -60,6 +60,8 @@ PNode* p_c_ident(Id id);
PNode* p_c_macro(Id id);
PNode* p_prot_header(Module* m);
PNode* p_type_header(Module* m);
PNode* p_func_header(Module* m);
void output_func(PRoot* out,
@ -77,6 +79,10 @@ 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);
PNode* p_prot_include(Module* m);
PNode* p_func_include(Module* m);

View File

@ -12,7 +12,7 @@ PNode* p_enum_decl(EnumDef* e){
"\t~ = ~\n"
"} ~;\n",
p_for(e->alternatives, p_enum_member, t),
p_macro_name(t, NULL, "LAST"),
p_macro_name(t, NULL, "last"),
p_macro_name(t, NULL,
g_slist_last(e->alternatives)->data),
p_primtype(t));
@ -50,6 +50,6 @@ void output_enum_type_init(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));
pr_put(out, "type", p_enum_decl(e));
}

View File

@ -23,7 +23,7 @@ PNode* p_flags_decl(FlagsDef* e){
p_for(e->flags, p_flags_member, &d),
p_primtype(d.t),
p_primtype(d.t),
p_macro_name(d.t, NULL, "LAST"),
p_macro_name(d.t, NULL, "last"),
p_macro_name(d.t, NULL, g_slist_last(e->flags)->data));
}
@ -58,7 +58,7 @@ void output_flags_type_init(PRoot* out, FlagsDef* e){
void output_flags(PRoot* out, Def* d){
FlagsDef* f = (FlagsDef*) d;
pr_add(out, "type", p_flags_decl(f));
pr_put(out, "type", p_flags_decl(f));
output_flags_type_init(out, f);
}

View File

@ -118,7 +118,7 @@ void output_connector(PRoot* out, Method* m){
p_varname(DEF(MEMBER(m)->my_class)->type,
p_fmt("connect_~",
p_c_ident(MEMBER(m)->name))),
p_fmt("~ handler, gpointer user_data",
p_fmt("\n\t~ handler,\n\tgpointer user_data",
p_signal_handler_type(m)),
par,
p_fmt("\t~gtk_signal_connect((GtkObject*)~,\n"
@ -198,8 +198,10 @@ void output_method(PRoot* out, Method* m){
p_for(m->params, p_param_marshtype, p_nil),
p_signal_id(m)));
pr_add(out, "functions",
p_fmt("typedef ~ (*~)(~, gpointer);\n",
pr_put(out, "functions",
p_fmt("typedef ~ (*~)("
"~,\n"
"\tgpointer);\n",
p_type(&m->ret_type),
p_signal_handler_type(m),
p_params(par, &o)));
@ -212,7 +214,7 @@ void output_method(PRoot* out, Method* m){
case METH_DIRECT:
o.names=TRUE;
o.types=TRUE;
pr_add(out, "source_head",
pr_put(out, "source_head",
p_fmt("static ~ ~_~_real (~);\n",
p_type(&m->ret_type),
p_c_ident(t->name),
@ -341,9 +343,13 @@ void output_member_cb(gpointer a, gpointer b){
PNode* p_class_macros(ObjectDef* o ){
PrimType* t=DEF(o)->type;
return p_fmt("#define ~(o) GTK_CHECK_TYPE(o, ~)\n",
p_macro_name(t, "IS", NULL),
p_macro_name(t, "TYPE", NULL));
return p_fmt("#define ~(o) GTK_CHECK_TYPE(o, ~)\n"
"#define ~(o) GTK_CHECK_CAST(o, ~, ~)\n",
p_macro_name(t, "is", NULL),
p_macro_name(t, "type", NULL),
p_macro_name(t, NULL, NULL),
p_macro_name(t, "type", NULL),
p_primtype(t));
}
void output_object_type_init(PRoot* out, ObjectDef* o){
@ -374,17 +380,13 @@ void output_object_type_init(PRoot* out, ObjectDef* o){
p_varname(t, p_str("init")),
type_var,
type_var,
p_macro_name(o->parent, "TYPE", NULL),
p_macro_name(o->parent, "type", NULL),
type_var));
}
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",
pr_put(out, "source_head",
p_fmt("static inline void ~ (~ ~);\n",
p_varname(DEF(o)->type, p_str("init_real")),
p_type(&o->self_type[FALSE]),
@ -402,7 +404,7 @@ void output_object_init(PRoot* out, ObjectDef* o){
}
void output_class_init(PRoot* out, ObjectDef* o){
pr_add(out, "source_head",
pr_put(out, "source_head",
p_fmt("static inline void ~ (~* klass);\n",
p_varname(DEF(o)->type, p_str("class_init_real")),
p_class_name(DEF(o)->type)));
@ -414,6 +416,7 @@ void output_class_init(PRoot* out, ObjectDef* o){
NULL,
p_fmt("\tGtkObjectClass* obklass = "
"(GtkObjectClass*) klass;\n"
"\t(void) obklass;\n"
"~"
"~"
"\t~ (klass);\n",
@ -424,13 +427,17 @@ void output_class_init(PRoot* out, ObjectDef* o){
void output_object(PRoot* out, Def* d){
ObjectDef* o = (ObjectDef*)d;
pr_put(out, "func_parent_depends", o->parent->module);
pr_put(out, "prot_depends", d->type->module);
pr_put(out, "prot_parent_depends", o->parent->module);
pr_put(out, "source_prot_depends", d->type->module);
output_object_type_init(out, o);
output_class_init(out, o);
output_object_init(out, o);
pr_add(out, "protected", p_class_decl(o));
pr_add(out, "protected", p_class_body(o));
pr_add(out, "type", p_object_decl(o));
pr_add(out, "type", p_class_macros(o));
pr_add(out, "protected", p_object_body(o));
pr_put(out, "protected", p_class_decl(o));
pr_put(out, "protected", p_class_body(o));
pr_put(out, "type", p_object_decl(o));
pr_put(out, "type", p_class_macros(o));
pr_put(out, "protected", p_object_body(o));
g_slist_foreach(o->members, output_member_cb, out);
}

View File

@ -1,13 +1,17 @@
%{
#include "gcg.h"
#include "parse.h"
#define YYDEBUG 1
static Package* current_package;
static Module* current_module;
Module* current_module;
static ObjectDef* current_class;
static Method* current_method;
static PrimType* root_class;
static GSList* imports_list;
%}
@ -71,11 +75,14 @@ static GSList* imports_list;
%token T_SIGNAL
%token T_FOREIGN
%token T_PACKAGE
%token T_ROOT
%token T_CHAR
%token<id> T_IDENT
%token<id> T_HEADERNAME
%token<str> T_STRING
%type<id> maybeident
%type<id> ident
%type<id> headerdef
%type<fund_type> fundtype
@ -110,7 +117,17 @@ start_symbol: deffile ;
deffile: declarations definitions;
declarations: /* empty */ | declarations package;
declarations: /* empty */ | declarations package | declarations rootdef;
rootdef: T_ROOT primtype T_END {
if($2->kind != TYPE_OBJECT)
g_error("Bad root type: %s.%s",
$2->module->package->name,
$2->name);
root_class = $2;
};
definitions: current_module_def deflist;
@ -132,13 +149,18 @@ importlist: ident {
imports_list = g_slist_prepend(imports_list, p);
}
package: T_PACKAGE ident T_OPEN_B {
Package* p = get_pkg($2);
package: T_PACKAGE maybeident headerdef T_OPEN_B {
Package* p;
Id i = $2;
if(!i)
i = GET_ID("");
p = get_pkg(i);
if(!p){
p = g_new(Package, 1);
p->name = $2;
p->name = i;
p->type_hash = g_hash_table_new(NULL, NULL);
p->mod_hash = g_hash_table_new(NULL, NULL);
p->headerbase = $3;
put_pkg(p);
}
current_package = p;
@ -165,8 +187,13 @@ headerdef: /* empty */ {
}| T_HEADERNAME;
maybeident: ident | /* empty */ {
$$ = NULL;
};
module: T_MODULE ident headerdef T_OPEN_B {
module: T_MODULE maybeident headerdef T_OPEN_B {
Module* m = get_mod(current_package, $2);
if(!m){
m = g_new(Module, 1);
@ -186,15 +213,21 @@ fundtype: T_INT {
$$ = TYPE_INT;
} | T_DOUBLE {
$$ = TYPE_DOUBLE;
} | T_BOXED {
$$ = TYPE_FOREIGN;
} | T_CLASS {
$$ = TYPE_OBJECT;
} | T_ENUM {
$$ = TYPE_ENUM;
} | T_FLAGS {
$$ = TYPE_FLAGS;
}
} | T_BOXED {
$$ = TYPE_BOXED;
} | T_FOREIGN {
$$ = TYPE_FOREIGN;
} | T_CHAR {
$$ = TYPE_CHAR;
};
simpledecl: fundtype ident T_END {
PrimType* t = g_new(PrimType, 1);
@ -214,7 +247,12 @@ semitype: const_def primtype {
$$.indirection++;
};
type: semitype | semitype T_NOTNULLPTR {
type: semitype {
if(!$$.indirection){
g_assert($$.prim->kind != TYPE_OBJECT);
g_assert($$.prim->kind != TYPE_BOXED);
}
} | semitype T_NOTNULLPTR {
$$ = $1;
$$.indirection++;
$$.notnull = TRUE;
@ -231,14 +269,18 @@ typeorvoid: type | T_VOID {
};
primtype: ident T_SCOPE ident {
Package* p=get_pkg($1);
primtype: maybeident T_SCOPE ident {
Id i = $1;
Package* p;
PrimType* t;
if(!i)
i = GET_ID("");
p = get_pkg(i);
if(!p)
g_error("Unknown package %s!", $1);
g_error("Unknown package %s!", i);
t = get_type(p, $3);
if(!t)
g_error("Unknown type %s:%s", $1, $3);
g_error("Unknown type %s:%s", i, $3);
$$ = t;
} | ident {
Package* p = current_module->package;
@ -358,7 +400,8 @@ flagsdef: T_FLAGS primtype docstring T_OPEN_B idlist T_CLOSE_B T_END {
};
parent: /* empty */{
$$=NULL;
g_assert(root_class);
$$ = root_class;
} | T_INHERITANCE primtype{
$$=$2;
}

View File

@ -117,28 +117,22 @@ void p_unref(PNode* 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);
p_write(func(value), c->f, c->p);
else
p_write(value, c->w);
p_write(value, c->f, c->p);
}
static void p_write(PNode* node, PWrite* w){
void p_write(PNode* node, FILE* f, PRoot* r){
g_assert(f);
BE_NODE(node);
switch(node->type){
case NODE_DATA:{
@ -147,25 +141,40 @@ static void p_write(PNode* node, PWrite* w){
for(i = 0; i < n; i++){
if(bl[i].str)
fputs(bl[i].str, w->f);
p_write(bl[i].node, w);
fputs(bl[i].str, f);
p_write(bl[i].node, f, r);
}
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);
case NODE_COLLECT:
if(r){
GHashTable* h = g_datalist_id_get_data(&r->data,
node->u.c.tag);
PCollect c;
c.f = f;
c.p = r;
c.n = node;
if(h)
g_hash_table_foreach(h, cb_pwrite, &c);
}
break;
}
}
}
gchar* p_to_str(PNode* n, PRoot* pr){
FILE* f = tmpfile();
glong len;
gchar* buf;
p_write(n, f, pr);
len = ftell(f);
rewind(f);
buf = g_new(gchar, len+1);
fread(buf, len, 1, f);
buf[len]='\0';
fclose(f);
return buf;
}
static PNode* p_simple_string(gchar* str){
@ -180,6 +189,9 @@ static PNode* p_simple_string(gchar* str){
PNode* p_str(const gchar* str){
PNode* n;
if(!str)
return p_nil;
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);
@ -270,7 +282,8 @@ PRoot* pr_new(void){
return pr;
}
void pr_add(PRoot* pr, const gchar* tag, PNode* node){
/*
void pr_add(PRoot* pr, const gchar* tag, PNode* node){
PRNode* n;
g_assert(pr);
BE_NODE(node);
@ -282,7 +295,7 @@ void pr_add(PRoot* pr, const gchar* tag, PNode* node){
pr->nodes = g_list_prepend(pr->nodes, n);
p_ref(node);
}
*/
void pr_put(PRoot* pr, const gchar* tag, gpointer datum){
GHashTable* h = g_datalist_get_data(&pr->data, tag);
if(!h){
@ -293,38 +306,6 @@ void pr_put(PRoot* pr, const gchar* tag, gpointer datum){
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;
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;

View File

@ -19,13 +19,15 @@ PNode* p_fmt(const gchar* f, ...);
PNode* p_lst(PNode* n, ...);
PNode* p_for(GSList* l, PNodeCreateFunc func, gpointer user_data);
PNode* p_col(const gchar* tag, PNodeCreateFunc func);
void p_write(PNode* node, FILE* f, PRoot* r);
gchar* p_to_str(PNode* n, PRoot* pr);
PRoot* pr_new(void);
void pr_add(PRoot* root, const gchar* tag, PNode* node);
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);