From: Jürg Billeter Date: Thu, 25 May 2006 16:24:59 +0000 (+0000) Subject: support ELLIPSIS, use g_strdup instead of strdup support variable argument X-Git-Tag: VALA_0_0_1~43 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=35bd6909ba2b8467ba95dfe6360e7a7e227115c8;p=platform%2Fupstream%2Fvala.git support ELLIPSIS, use g_strdup instead of strdup support variable argument 2006-05-25 Jürg Billeter * vala/scanner.l: support ELLIPSIS, use g_strdup instead of strdup * vala/parser.y: support variable argument lists, type access modifiers * vala/valareport.vala: class to handle error reporting * vala/valasymbolbuilder.vala: switch to new error reporting scheme * vala/valasymbolresolver.vala: switch to new error reporting scheme * vala/valasemanticanalyzer.vala: process Constant and EnumValue symbol dependencies, check method argument types, find types of unary and binary expressions, remove dummy field, switch to new error reporting scheme * vala/valacodegenerator.vala: support calling functions with variable argument lists, support break and continue statements, remove dummy fields, switch to new error reporting scheme * vala/valainterfacewriter.vala: visitor to write public vala api in one file * vala/valasourcefile.vala: support field and property symbol dependencies, remove dummy field * vala/valaclass.vala: add is_abstract field * vala/valaenumvalue.vala: remove dummy field * vala/valaformalparameter.vala: add ellipsis property * vala/valamemberaccessibility.vala: add INTERNAL * vala/valamethod.vala: make parameters public, remove dummy field * vala/valaproperty.vala: remove dummy field * vala/valasymbol.vala: add name field and get_full_name method * vala/valatype.vala: add access field * vala/valatypereference.vala: switch to new error reporting scheme * ccode/valaccodeblock.vala: improve formatting * ccode/valaccodeifstatement.vala: improve formatting * ccode/valaccodewriter.vala: improve formatting * compiler/valacompiler.vala: add error handling, support multiple vapi directories, add --library option to generate public vala api * vapi/glib-2.0.vala: moved from bindings, add static GLib.stdout field, correctly mark functions with variable argument lists, add File.test method * configure.ac,Makefile.am,ccode/Makefile.am,vala/Makefile.am, vapi/Makefile.am,compiler/Makefile.am: add build system * remove valac subdirectory: Bootstrap compiler is now obsolete. svn path=/trunk/; revision=36 --- diff --git a/vala/ChangeLog b/vala/ChangeLog index d0fbbf2..f52afb9 100644 --- a/vala/ChangeLog +++ b/vala/ChangeLog @@ -1,3 +1,44 @@ +2006-05-25 Jürg Billeter + + * vala/scanner.l: support ELLIPSIS, use g_strdup instead of strdup + * vala/parser.y: support variable argument lists, type access modifiers + * vala/valareport.vala: class to handle error reporting + * vala/valasymbolbuilder.vala: switch to new error reporting scheme + * vala/valasymbolresolver.vala: switch to new error reporting scheme + * vala/valasemanticanalyzer.vala: process Constant and EnumValue symbol + dependencies, check method argument types, find types of unary and + binary expressions, remove dummy field, switch to new error reporting + scheme + * vala/valacodegenerator.vala: support calling functions with variable + argument lists, support break and continue statements, remove dummy fields, + switch to new error reporting scheme + * vala/valainterfacewriter.vala: visitor to write public vala api in one + file + * vala/valasourcefile.vala: support field and property symbol + dependencies, remove dummy field + * vala/valaclass.vala: add is_abstract field + * vala/valaenumvalue.vala: remove dummy field + * vala/valaformalparameter.vala: add ellipsis property + * vala/valamemberaccessibility.vala: add INTERNAL + * vala/valamethod.vala: make parameters public, remove dummy field + * vala/valaproperty.vala: remove dummy field + * vala/valasymbol.vala: add name field and get_full_name method + * vala/valatype.vala: add access field + * vala/valatypereference.vala: switch to new error reporting scheme + * ccode/valaccodeblock.vala: improve formatting + * ccode/valaccodeifstatement.vala: improve formatting + * ccode/valaccodewriter.vala: improve formatting + * compiler/valacompiler.vala: add error handling, support multiple vapi + directories, add --library option to generate public vala api + * vapi/glib-2.0.vala: moved from bindings, add static GLib.stdout field, + correctly mark functions with variable argument lists, add File.test + method + + * configure.ac,Makefile.am,ccode/Makefile.am,vala/Makefile.am, + vapi/Makefile.am,compiler/Makefile.am: add build system + + * remove valac subdirectory: Bootstrap compiler is now obsolete. + 2006-05-24 Jürg Billeter Compiler is now self-hosting. diff --git a/vala/Makefile.am b/vala/Makefile.am index d55e502..596f65e 100644 --- a/vala/Makefile.am +++ b/vala/Makefile.am @@ -1,5 +1,8 @@ NULL = SUBDIRS = \ - valac \ + ccode \ + vala \ + compiler \ + vapi \ $(NULL) diff --git a/vala/ccode/Makefile.am b/vala/ccode/Makefile.am new file mode 100644 index 0000000..e26f458 --- /dev/null +++ b/vala/ccode/Makefile.am @@ -0,0 +1,144 @@ +NULL = + +INCLUDES = \ + $(GLIB_CFLAGS) \ + $(NULL) + +noinst_LTLIBRARIES = \ + libvalaccode.la + $(NULL) + +libvalaccode_la_VALASOURCES = \ + valaccodeassignment.vala \ + valaccodebinaryexpression.vala \ + valaccodeblock.vala \ + valaccodebreakstatement.vala \ + valaccodecasestatement.vala \ + valaccodecomment.vala \ + valaccodeconstant.vala \ + valaccodecontinuestatement.vala \ + valaccodedeclaration.vala \ + valaccodedeclarator.vala \ + valaccodeemptystatement.vala \ + valaccodeenum.vala \ + valaccodeexpressionstatement.vala \ + valaccodeexpression.vala \ + valaccodeformalparameter.vala \ + valaccodeforstatement.vala \ + valaccodefragment.vala \ + valaccodefunctioncall.vala \ + valaccodefunctiondeclarator.vala \ + valaccodefunction.vala \ + valaccodeidentifier.vala \ + valaccodeifstatement.vala \ + valaccodeincludedirective.vala \ + valaccodeinitializerlist.vala \ + valaccodemacroreplacement.vala \ + valaccodememberaccess.vala \ + valaccodemodifiers.vala \ + valaccodenewline.vala \ + valaccodenode.vala \ + valaccodeoncesection.vala \ + valaccodeparenthesizedexpression.vala \ + valaccodereturnstatement.vala \ + valaccodestatement.vala \ + valaccodestruct.vala \ + valaccodeswitchstatement.vala \ + valaccodetypedefinition.vala \ + valaccodeunaryexpression.vala \ + valaccodevariabledeclarator.vala \ + valaccodewhilestatement.vala \ + valaccodewriter.vala \ + $(NULL) + +libvalaccode_la_SOURCES = \ + valaccodeassignment.c \ + valaccodeassignment.h \ + valaccodebinaryexpression.c \ + valaccodebinaryexpression.h \ + valaccodeblock.c \ + valaccodeblock.h \ + valaccodebreakstatement.c \ + valaccodebreakstatement.h \ + valaccodecasestatement.c \ + valaccodecasestatement.h \ + valaccodecomment.c \ + valaccodecomment.h \ + valaccodeconstant.c \ + valaccodeconstant.h \ + valaccodecontinuestatement.c \ + valaccodecontinuestatement.h \ + valaccodedeclaration.c \ + valaccodedeclaration.h \ + valaccodedeclarator.c \ + valaccodedeclarator.h \ + valaccodeemptystatement.c \ + valaccodeemptystatement.h \ + valaccodeenum.c \ + valaccodeenum.h \ + valaccodeexpression.c \ + valaccodeexpression.h \ + valaccodeexpressionstatement.c \ + valaccodeexpressionstatement.h \ + valaccodeformalparameter.c \ + valaccodeformalparameter.h \ + valaccodeforstatement.c \ + valaccodeforstatement.h \ + valaccodefragment.c \ + valaccodefragment.h \ + valaccodefunction.c \ + valaccodefunctioncall.c \ + valaccodefunctioncall.h \ + valaccodefunctiondeclarator.c \ + valaccodefunctiondeclarator.h \ + valaccodefunction.h \ + valaccodeidentifier.c \ + valaccodeidentifier.h \ + valaccodeifstatement.c \ + valaccodeifstatement.h \ + valaccodeincludedirective.c \ + valaccodeincludedirective.h \ + valaccodeinitializerlist.c \ + valaccodeinitializerlist.h \ + valaccodemacroreplacement.c \ + valaccodemacroreplacement.h \ + valaccodememberaccess.c \ + valaccodememberaccess.h \ + valaccodemodifiers.c \ + valaccodemodifiers.h \ + valaccodenewline.c \ + valaccodenewline.h \ + valaccodenode.c \ + valaccodenode.h \ + valaccodeoncesection.c \ + valaccodeoncesection.h \ + valaccodeparenthesizedexpression.c \ + valaccodeparenthesizedexpression.h \ + valaccodereturnstatement.c \ + valaccodereturnstatement.h \ + valaccodestatement.c \ + valaccodestatement.h \ + valaccodestruct.c \ + valaccodestruct.h \ + valaccodeswitchstatement.c \ + valaccodeswitchstatement.h \ + valaccodetypedefinition.c \ + valaccodetypedefinition.h \ + valaccodeunaryexpression.c \ + valaccodeunaryexpression.h \ + valaccodevariabledeclarator.c \ + valaccodevariabledeclarator.h \ + valaccodewhilestatement.c \ + valaccodewhilestatement.h \ + valaccodewriter.c \ + valaccodewriter.h \ + $(NULL) + +$(subst .vala,.c,$(libvalaccode_la_VALASOURCES)) $(subst .vala,.h,$(libvalaccode_la_VALASOURCES)) valaccode.vala: $(libvalaccode_la_VALASOURCES) + $(VALAC) --vapidir $(srcdir)/../vapi --library valaccode $^ + +libvalaccode_la_LIBADD = \ + $(GLIB_LIBS) \ + $(NULL) + +EXTRA_DIST = $(libvalaccode_la_VALASOURCES) valaccode.vala diff --git a/vala/ccode/valaccodeblock.vala b/vala/ccode/valaccodeblock.vala index b82260e..4b853d9 100644 --- a/vala/ccode/valaccodeblock.vala +++ b/vala/ccode/valaccodeblock.vala @@ -25,6 +25,7 @@ using GLib; namespace Vala { public class CCodeBlock : CCodeStatement { List statements; + public bool suppress_newline; public void add_statement (CCodeNode statement) { /* allow generic nodes to include comments */ @@ -34,11 +35,13 @@ namespace Vala { public override void write (CCodeWriter writer) { writer.write_begin_block (); foreach (CCodeNode statement in statements) { - if (statement != null) { - statement.write (writer); - } + statement.write (writer); } writer.write_end_block (); + + if (!suppress_newline) { + writer.write_newline (); + } } } } diff --git a/vala/ccode/valaccodeifstatement.vala b/vala/ccode/valaccodeifstatement.vala index 2de1133..b5fc61d 100644 --- a/vala/ccode/valaccodeifstatement.vala +++ b/vala/ccode/valaccodeifstatement.vala @@ -27,22 +27,41 @@ namespace Vala { public CCodeExpression condition { get; construct; } public CCodeStatement true_statement { get; construct; } public CCodeStatement false_statement { get; construct; } + public bool else_if; public override void write (CCodeWriter writer) { - writer.write_indent (); + if (!else_if) { + writer.write_indent (); + } else { + writer.write_string (" "); + } writer.write_string ("if ("); if (condition != null) { condition.write (writer); } writer.write_string (")"); + + /* else shouldn't be on a separate line */ + if (false_statement != null && true_statement is CCodeBlock) { + var cblock = (CCodeBlock) true_statement; + cblock.suppress_newline = true; + } + true_statement.write (writer); if (false_statement != null) { if (writer.bol) { writer.write_indent (); - writer.write_string ("else "); + writer.write_string ("else"); } else { - writer.write_string (" else "); + writer.write_string (" else"); + } + + /* else if should be on one line */ + if (false_statement is CCodeIfStatement) { + var cif = (CCodeIfStatement) false_statement; + cif.else_if = true; } + false_statement.write (writer); } } diff --git a/vala/ccode/valaccodewriter.vala b/vala/ccode/valaccodewriter.vala index cac8c52..57065e3 100644 --- a/vala/ccode/valaccodewriter.vala +++ b/vala/ccode/valaccodewriter.vala @@ -61,6 +61,8 @@ namespace Vala { public void write_begin_block () { if (!bol) { stream.putc (' '); + } else { + write_indent (); } stream.putc ('{'); write_newline (); diff --git a/vala/compiler/Makefile.am b/vala/compiler/Makefile.am new file mode 100644 index 0000000..55201e0 --- /dev/null +++ b/vala/compiler/Makefile.am @@ -0,0 +1,31 @@ +NULL = + +INCLUDES = \ + $(GLIB_CFLAGS) \ + -I../ccode \ + -I../vala \ + $(NULL) + +bin_PROGRAMS = \ + valac \ + $(NULL) + +valac_VALASOURCES = \ + valacompiler.vala \ + $(NULL) + +valac_SOURCES = \ + valacompiler.c \ + valacompiler.h \ + $(NULL) + +$(subst .vala,.c,$(valac_VALASOURCES)) $(subst .vala,.h,$(valac_VALASOURCES)): $(valac_VALASOURCES) + $(VALAC) --vapidir $(srcdir)/../vapi --vapidir ../ccode --pkg valaccode --vapidir ../vala --pkg vala $^ + +valac_LDADD = \ + $(GLIB_LIBS) \ + ../ccode/libvalaccode.la \ + ../vala/libvala.la \ + $(NULL) + +EXTRA_DIST = $(valac_VALASOURCES) diff --git a/vala/compiler/valacompiler.vala b/vala/compiler/valacompiler.vala index e12748c..84d1af2 100644 --- a/vala/compiler/valacompiler.vala +++ b/vala/compiler/valacompiler.vala @@ -27,51 +27,143 @@ namespace Vala { static string directory; static int version; static string[] sources; - static string package_directory = "/usr/share/vala/pkg"; + static string[] vapi_directories; + static string library; static string[] packages; CodeContext context; const OptionEntry[] options = { - { "pkgdir", 0, 0, OptionArg.FILENAME, out package_directory, "Look for package bindings in DIRECTORY", "DIRECTORY" }, + { "vapidir", 0, 0, OptionArg.FILENAME_ARRAY, out vapi_directories, "Look for package bindings in DIRECTORY", "DIRECTORY..." }, { "pkg", 0, 0, OptionArg.STRING_ARRAY, out packages, "Include binding for PACKAGE", "PACKAGE..." }, + { "library", 0, 0, OptionArg.STRING, out library, "Library name", "NAME" }, { "directory", 'd', 0, OptionArg.FILENAME, out directory, "Output directory", "DIRECTORY" }, { "version", 0, 0, OptionArg.NONE, ref version, "Display version number", null }, { "", 0, 0, OptionArg.FILENAME_ARRAY, out sources, null, "FILE..." }, { null } }; - void run () { + private int quit () { + if (Report.get_errors () == 0) { + stdout.printf ("Compilation succeeded - %d warning(s)\n", Report.get_warnings ()); + return 0; + } else { + stdout.printf ("Compilation failed: %d error(s), %d warning(s)\n", Report.get_errors (), Report.get_warnings ()); + return 1; + } + } + + private ref string get_package_path (string pkg) { + var basename = "%s.vala".printf (pkg); + + if (vapi_directories != null) { + foreach (string vapidir in vapi_directories) { + var filename = Path.build_filename (vapidir, basename, null); + if (File.test (filename, FileTest.EXISTS)) { + return filename; + } + } + } + + var filename = Path.build_filename ("/usr/share/vala/vapi", basename, null); + if (File.test (filename, FileTest.EXISTS)) { + return filename; + } + + return null; + } + + private bool add_package (string pkg) { + var package_path = get_package_path (pkg); + + if (package_path == null) { + return false; + } + + context.add_source_file (new SourceFile (filename = package_path, pkg = true)); + + return true; + } + + private int run () { context = new CodeContext (); - context.add_source_file (new SourceFile (filename = Path.build_filename (package_directory, "glib-2.0.vala", null), pkg = true)); - + /* default package */ + if (!add_package ("glib-2.0")) { + Report.error (null, "glib-2.0 not found in specified Vala API directories"); + } + if (packages != null) { foreach (string package in packages) { - context.add_source_file (new SourceFile (filename = Path.build_filename (package_directory, "%s.vala".printf (package), null), pkg = true)); + if (!add_package (package)) { + Report.error (null, "%s not found in specified Vala API directories".printf (package)); + } } } + if (Report.get_errors () > 0) { + return quit (); + } + foreach (string source in sources) { - context.add_source_file (new SourceFile (filename = source)); + if (File.test (source, FileTest.EXISTS)) { + context.add_source_file (new SourceFile (filename = source)); + } else { + Report.error (null, "%s not found".printf (source)); + } + } + + if (Report.get_errors () > 0) { + return quit (); } var parser = new Parser (); parser.parse (context); + if (Report.get_errors () > 0) { + return quit (); + } + var builder = new SymbolBuilder (); builder.build (context); + if (Report.get_errors () > 0) { + return quit (); + } + var resolver = new SymbolResolver (); resolver.resolve (context); + if (Report.get_errors () > 0) { + return quit (); + } + var attributeprocessor = new AttributeProcessor (); attributeprocessor.process (context); + if (Report.get_errors () > 0) { + return quit (); + } + var analyzer = new SemanticAnalyzer (); analyzer.analyze (context); + if (Report.get_errors () > 0) { + return quit (); + } + var code_generator = new CodeGenerator (); code_generator.emit (context); + + if (Report.get_errors () > 0) { + return quit (); + } + + if (library != null) { + var interface_writer = new InterfaceWriter (); + interface_writer.write_file (context, "%s.vala".printf (library)); + } + + return quit (); } static int main (int argc, string[] argv) { @@ -99,9 +191,7 @@ namespace Vala { } var compiler = new Compiler (); - compiler.run (); - - return 0; + return compiler.run (); } } } diff --git a/vala/configure.ac b/vala/configure.ac index 9fd89ae..6a171d5 100644 --- a/vala/configure.ac +++ b/vala/configure.ac @@ -11,17 +11,23 @@ AC_PROG_LIBTOOL AM_PROG_LEX AC_PROG_YACC +AC_PATH_PROG(VALAC, valac, valac) +AC_SUBST(VALAC) + AC_SUBST(CFLAGS) AC_SUBST(CPPFLAGS) AC_SUBST(LDFLAGS) GLIB_REQUIRED=2.10.0 -PKG_CHECK_MODULES(GLIB, glib-2.0 >= $GLIB_REQUIRED) +PKG_CHECK_MODULES(GLIB, glib-2.0 >= $GLIB_REQUIRED gobject-2.0 >= $GLIB_REQUIRED) AC_SUBST(GLIB_CFLAGS) AC_SUBST(GLIB_LIBS) AC_CONFIG_FILES([Makefile - valac/Makefile]) + ccode/Makefile + vala/Makefile + compiler/Makefile + vapi/Makefile]) AC_OUTPUT diff --git a/vala/vala/Makefile.am b/vala/vala/Makefile.am new file mode 100644 index 0000000..2a0e267 --- /dev/null +++ b/vala/vala/Makefile.am @@ -0,0 +1,238 @@ +NULL = + +INCLUDES = \ + $(GLIB_CFLAGS) \ + -I ../ccode \ + $(NULL) + +BUILT_SOURCES = parser.h +AM_YFLAGS = -d + +noinst_LTLIBRARIES = \ + libvala.la + $(NULL) + +libvala_la_VALASOURCES = \ + valaassignment.vala \ + valaattributeprocessor.vala \ + valaattribute.vala \ + valabinaryexpression.vala \ + valablock.vala \ + valabooleanliteral.vala \ + valabreakstatement.vala \ + valacastexpression.vala \ + valacharacterliteral.vala \ + valaclass.vala \ + valacodecontext.vala \ + valacodegenerator.vala \ + valacodenode.vala \ + valacodevisitor.vala \ + valaconditionalexpression.vala \ + valaconstant.vala \ + valacontinuestatement.vala \ + valadeclarationstatement.vala \ + valaemptystatement.vala \ + valaenum.vala \ + valaenumvalue.vala \ + valaexpressionstatement.vala \ + valaexpression.vala \ + valafield.vala \ + valaforeachstatement.vala \ + valaformalparameter.vala \ + valaforstatement.vala \ + valaifstatement.vala \ + valainitializerlist.vala \ + valaintegerliteral.vala \ + valainterfacewriter.vala \ + valainvocationexpression.vala \ + valaliteralexpression.vala \ + valaliteral.vala \ + valalocalvariabledeclaration.vala \ + valamemberaccessibility.vala \ + valamemberaccess.vala \ + valamethod.vala \ + valanamedargument.vala \ + valanamespacereference.vala \ + valanamespace.vala \ + valanullliteral.vala \ + valaobjectcreationexpression.vala \ + valaparenthesizedexpression.vala \ + valaparser.vala \ + valapostfixexpression.vala \ + valapropertyaccessor.vala \ + valaproperty.vala \ + valareport.vala \ + valareturnstatement.vala \ + valasemanticanalyzer.vala \ + valasimplename.vala \ + valasourcefilecycle.vala \ + valasourcefile.vala \ + valasourcereference.vala \ + valastatement.vala \ + valastringliteral.vala \ + valastruct.vala \ + valasymbolbuilder.vala \ + valasymbolresolver.vala \ + valasymbol.vala \ + valatypecheck.vala \ + valatypeparameter.vala \ + valatypereference.vala \ + valatype.vala \ + valaunaryexpression.vala \ + valavariabledeclarator.vala \ + valawhilestatement.vala \ + $(NULL) + +libvala_la_SOURCES = \ + parser.y \ + scanner.l \ + vala.h \ + valaassignment.c \ + valaassignment.h \ + valaattribute.c \ + valaattribute.h \ + valaattributeprocessor.c \ + valaattributeprocessor.h \ + valabinaryexpression.c \ + valabinaryexpression.h \ + valablock.c \ + valablock.h \ + valabooleanliteral.c \ + valabooleanliteral.h \ + valabreakstatement.c \ + valabreakstatement.h \ + valacastexpression.c \ + valacastexpression.h \ + valacharacterliteral.c \ + valacharacterliteral.h \ + valaclass.c \ + valaclass.h \ + valacodecontext.c \ + valacodecontext.h \ + valacodegenerator.c \ + valacodegenerator.h \ + valacodenode.c \ + valacodenode.h \ + valacodevisitor.c \ + valacodevisitor.h \ + valaconditionalexpression.c \ + valaconditionalexpression.h \ + valaconstant.c \ + valaconstant.h \ + valacontinuestatement.c \ + valacontinuestatement.h \ + valadeclarationstatement.c \ + valadeclarationstatement.h \ + valaemptystatement.c \ + valaemptystatement.h \ + valaenum.c \ + valaenum.h \ + valaenumvalue.c \ + valaenumvalue.h \ + valaexpression.c \ + valaexpression.h \ + valaexpressionstatement.c \ + valaexpressionstatement.h \ + valafield.c \ + valafield.h \ + valaforeachstatement.c \ + valaforeachstatement.h \ + valaformalparameter.c \ + valaformalparameter.h \ + valaforstatement.c \ + valaforstatement.h \ + valaifstatement.c \ + valaifstatement.h \ + valainitializerlist.c \ + valainitializerlist.h \ + valaintegerliteral.c \ + valaintegerliteral.h \ + valainterfacewriter.c \ + valainterfacewriter.h \ + valainvocationexpression.c \ + valainvocationexpression.h \ + valaliteral.c \ + valaliteralexpression.c \ + valaliteralexpression.h \ + valaliteral.h \ + valalocalvariabledeclaration.c \ + valalocalvariabledeclaration.h \ + valamemberaccess.c \ + valamemberaccess.h \ + valamemberaccessibility.c \ + valamemberaccessibility.h \ + valamethod.c \ + valamethod.h \ + valanamedargument.c \ + valanamedargument.h \ + valanamespace.c \ + valanamespace.h \ + valanamespacereference.c \ + valanamespacereference.h \ + valanullliteral.c \ + valanullliteral.h \ + valaobjectcreationexpression.c \ + valaobjectcreationexpression.h \ + valaparenthesizedexpression.c \ + valaparenthesizedexpression.h \ + valaparser.c \ + valaparser.h \ + valapostfixexpression.c \ + valapostfixexpression.h \ + valapropertyaccessor.c \ + valapropertyaccessor.h \ + valaproperty.c \ + valaproperty.h \ + valareport.c \ + valareport.h \ + valareturnstatement.c \ + valareturnstatement.h \ + valasemanticanalyzer.c \ + valasemanticanalyzer.h \ + valasimplename.c \ + valasimplename.h \ + valasourcefile.c \ + valasourcefilecycle.c \ + valasourcefilecycle.h \ + valasourcefile.h \ + valasourcereference.c \ + valasourcereference.h \ + valastatement.c \ + valastatement.h \ + valastringliteral.c \ + valastringliteral.h \ + valastruct.c \ + valastruct.h \ + valasymbolbuilder.c \ + valasymbolbuilder.h \ + valasymbol.c \ + valasymbol.h \ + valasymbolresolver.c \ + valasymbolresolver.h \ + valatype.c \ + valatypecheck.c \ + valatypecheck.h \ + valatype.h \ + valatypeparameter.c \ + valatypeparameter.h \ + valatypereference.c \ + valatypereference.h \ + valaunaryexpression.c \ + valaunaryexpression.h \ + valavariabledeclarator.c \ + valavariabledeclarator.h \ + valawhilestatement.c \ + valawhilestatement.h \ + $(NULL) + +vala.h: vala.vala + +$(subst .vala,.c,$(libvala_la_VALASOURCES)) $(subst .vala,.h,$(libvala_la_VALASOURCES)) vala.vala: $(libvala_la_VALASOURCES) + $(VALAC) --vapidir $(srcdir)/../vapi --vapidir ../ccode --pkg valaccode --library vala $^ + +libvala_la_LIBADD = \ + $(GLIB_LIBS) \ + ../ccode/libvalaccode.la \ + $(NULL) + +EXTRA_DIST = $(libvala_la_VALASOURCES) vala.vala diff --git a/vala/vala/parser.y b/vala/vala/parser.y index b876aad..4b3d925 100644 --- a/vala/vala/parser.y +++ b/vala/vala/parser.y @@ -93,6 +93,7 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg); %token CLOSE_PARENS ")" %token OPEN_BRACKET "[" %token CLOSE_BRACKET "]" +%token ELLIPSIS "..." %token DOT "." %token COLON ":" %token COMMA "," @@ -295,6 +296,11 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg); %% +opt_comma + : /* empty */ + | COMMA + ; + literal : boolean_literal | INTEGER_LITERAL @@ -951,6 +957,9 @@ class_declaration GList *l; current_struct = VALA_STRUCT (vala_class_new ($6, src_com (@6, $1))); VALA_CODE_NODE(current_struct)->attributes = $2; + if ($3 != 0) { + VALA_TYPE_(current_struct)->access = $3; + } for (l = $7; l != NULL; l = l->next) { vala_struct_add_type_parameter (current_struct, l->data); } @@ -1216,6 +1225,14 @@ opt_formal_parameter_list formal_parameter_list : fixed_parameters + | fixed_parameters COMMA ELLIPSIS + { + $$ = g_list_append ($1, vala_formal_parameter_new_ellipsis (src (@3))); + } + | ELLIPSIS + { + $$ = g_list_append (NULL, vala_formal_parameter_new_ellipsis (src (@1))); + } ; fixed_parameters @@ -1308,6 +1325,9 @@ struct_header vala_struct_add_type_parameter ($$, l->data); } VALA_CODE_NODE($$)->attributes = $2; + if ($3 != 0) { + VALA_TYPE_($$)->access = $3; + } } ; @@ -1363,6 +1383,9 @@ enum_declaration { GList *l; $$ = vala_enum_new ($5, src_com (@5, $1)); + if ($3 != 0) { + VALA_TYPE_($$)->access = $3; + } for (l = $6; l != NULL; l = l->next) { vala_enum_add_value ($$, l->data); } @@ -1381,7 +1404,7 @@ opt_enum_member_declarations { $$ = NULL; } - | enum_member_declarations + | enum_member_declarations opt_comma ; enum_member_declarations diff --git a/vala/vala/scanner.l b/vala/vala/scanner.l index 396f822..8a1e48c 100644 --- a/vala/vala/scanner.l +++ b/vala/vala/scanner.l @@ -64,6 +64,7 @@ literal ({literal_integer}|{literal_character}|{literal_string}) ")" { uploc; return CLOSE_PARENS; } "[" { uploc; return OPEN_BRACKET; } "]" { uploc; return CLOSE_BRACKET; } +"..." { uploc; return ELLIPSIS; } "." { uploc; return DOT; } ":" { uploc; return COLON; } "," { uploc; return COMMA; } @@ -107,7 +108,7 @@ literal ({literal_integer}|{literal_character}|{literal_string}) "/" { uploc; return DIV; } "%" { uploc; return PERCENT; } -"@"[[:alnum:]_]+ { uploc; yylval->str = strdup (yytext + 1); return IDENTIFIER; } +"@"[[:alnum:]_]+ { uploc; yylval->str = g_strdup (yytext + 1); return IDENTIFIER; } "abstract" { uploc; return ABSTRACT; } "break" { uploc; return BREAK; } diff --git a/vala/vala/valaclass.vala b/vala/vala/valaclass.vala index f3ec78c..2e34029 100644 --- a/vala/vala/valaclass.vala +++ b/vala/vala/valaclass.vala @@ -26,6 +26,7 @@ namespace Vala { public class Class : Struct { public List base_types; public Class base_class; + public bool is_abstract; List properties; diff --git a/vala/vala/valacodegenerator.vala b/vala/vala/valacodegenerator.vala index 7840145..60626e4 100644 --- a/vala/vala/valacodegenerator.vala +++ b/vala/vala/valacodegenerator.vala @@ -42,10 +42,6 @@ namespace Vala { CCodeEnum cenum; CCodeFunction function; CCodeBlock block; - - TypeReference reference; // dummy for dependency resolution - Symbol dummy_symbol; // dummy for dependency resolution - SourceFileCycle dummy_cycle; // dummy for dependency resolution public void emit (CodeContext context) { context.find_header_cycles (); @@ -650,7 +646,9 @@ namespace Vala { } public override void visit_formal_parameter (FormalParameter p) { - p.ccodenode = new CCodeFormalParameter (type_name = p.type_reference.get_cname (), name = p.name); + if (!p.ellipsis) { + p.ccodenode = new CCodeFormalParameter (type_name = p.type_reference.get_cname (), name = p.name); + } } public override void visit_begin_property (Property prop) { @@ -826,6 +824,14 @@ namespace Vala { stmt.ccodenode = cblock; } + public override void visit_break_statement (BreakStatement stmt) { + stmt.ccodenode = new CCodeBreakStatement (); + } + + public override void visit_continue_statement (ContinueStatement stmt) { + stmt.ccodenode = new CCodeContinueStatement (); + } + public override void visit_return_statement (ReturnStatement stmt) { if (stmt.return_expression == null) { stmt.ccodenode = new CCodeReturnStatement (); @@ -967,7 +973,7 @@ namespace Vala { } else if (expr.call is MemberAccess) { instance = ((MemberAccess) expr.call).inner.ccodenode; } else { - stderr.printf ("internal error: unsupported method invocation\n"); + Report.error (expr.source_reference, "unsupported method invocation"); } if (!m.instance_last) { ccall.add_argument (instance); @@ -1054,7 +1060,7 @@ namespace Vala { } else if (a.left is SimpleName) { ccall.add_argument (new CCodeIdentifier (name = "self")); } else { - stderr.printf ("error: unexpected lvalue in assignment\n"); + Report.error (a.source_reference, "unexpected lvalue in assignment"); } ccall.add_argument ((CCodeExpression) a.right.ccodenode); a.ccodenode = ccall; diff --git a/vala/vala/valaenumvalue.vala b/vala/vala/valaenumvalue.vala index 7136f8d..babacc7 100644 --- a/vala/vala/valaenumvalue.vala +++ b/vala/vala/valaenumvalue.vala @@ -27,8 +27,6 @@ namespace Vala { public string name { get; construct; } public IntegerLiteral value { get; construct; } public SourceReference source_reference { get; construct; } - - Symbol dummy_symbol; // dummy symbol for broken dependency handling public static ref EnumValue new (string name) { return (new EnumValue (name = name)); diff --git a/vala/vala/valaformalparameter.vala b/vala/vala/valaformalparameter.vala index 9a9b4e7..73fb5ae 100644 --- a/vala/vala/valaformalparameter.vala +++ b/vala/vala/valaformalparameter.vala @@ -26,14 +26,21 @@ namespace Vala { public class FormalParameter : CodeNode { public string name { get; construct; } public TypeReference type_reference { get; construct; } + public bool ellipsis { get; construct; } public SourceReference source_reference { get; construct; } public static ref FormalParameter new (string name, TypeReference type, SourceReference source) { return (new FormalParameter (name = name, type_reference = type, source_reference = source)); } + public static ref FormalParameter new_ellipsis (SourceReference source) { + return (new FormalParameter (ellipsis = true, source_reference = source)); + } + public override void accept (CodeVisitor visitor) { - type_reference.accept (visitor); + if (!ellipsis) { + type_reference.accept (visitor); + } visitor.visit_formal_parameter (this); } diff --git a/vala/vala/valainterfacewriter.vala b/vala/vala/valainterfacewriter.vala new file mode 100644 index 0000000..6709f5f --- /dev/null +++ b/vala/vala/valainterfacewriter.vala @@ -0,0 +1,295 @@ +/* valainterfacewriter.vala + * + * Copyright (C) 2006 Jürg Billeter + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: + * Jürg Billeter + */ + +using GLib; + +namespace Vala { + public class InterfaceWriter : CodeVisitor { + File stream; + + int indent; + /* at begin of line */ + bool bol = true; + + bool internal_scope = false; + + string current_cheader_filename; + + public void write_file (CodeContext context, string filename) { + stream = File.open (filename, "w"); + + /* we're only interested in non-pkg source files */ + foreach (SourceFile file in context.get_source_files ()) { + if (!file.pkg) { + file.accept (this); + } + } + + stream.close (); + } + + public override void visit_begin_source_file (SourceFile source_file) { + current_cheader_filename = source_file.get_cheader_filename (); + } + + public override void visit_begin_namespace (Namespace ns) { + if (ns.name == null) { + return; + } + + write_indent (); + write_string ("[CCode (cheader_filename = \"%s\")]".printf (current_cheader_filename)); + write_newline (); + + write_indent (); + write_string ("namespace "); + write_identifier (ns.name); + write_begin_block (); + } + + public override void visit_end_namespace (Namespace ns) { + if (ns.name == null) { + return; + } + + write_end_block (); + write_newline (); + } + + public override void visit_begin_class (Class cl) { + if (cl.access != MemberAccessibility.PUBLIC) { + internal_scope = true; + return; + } + + write_indent (); + write_string ("public "); + if (cl.is_abstract) { + write_string ("abstract "); + } + write_string ("class "); + write_identifier (cl.name); + if (cl.base_types != null) { + write_string (" : "); + + bool first = true; + foreach (TypeReference base_type in cl.base_types) { + if (!first) { + write_string (", "); + } else { + first = false; + } + write_string (base_type.type.symbol.get_full_name ()); + } + } + write_begin_block (); + } + + public override void visit_end_class (Class cl) { + if (cl.access != MemberAccessibility.PUBLIC) { + internal_scope = false; + return; + } + + write_end_block (); + write_newline (); + } + + public override void visit_begin_struct (Struct st) { + if (st.access != MemberAccessibility.PUBLIC) { + internal_scope = true; + return; + } + + write_indent (); + write_string ("public struct "); + write_identifier (st.name); + write_begin_block (); + } + + public override void visit_end_struct (Struct st) { + if (st.access != MemberAccessibility.PUBLIC) { + internal_scope = false; + return; + } + + write_end_block (); + write_newline (); + } + + public override void visit_begin_enum (Enum en) { + if (en.access != MemberAccessibility.PUBLIC) { + internal_scope = true; + return; + } + + write_indent (); + write_string ("public enum "); + write_identifier (en.name); + write_begin_block (); + } + + public override void visit_end_enum (Enum en) { + if (en.access != MemberAccessibility.PUBLIC) { + internal_scope = false; + return; + } + + write_end_block (); + write_newline (); + } + + public override void visit_enum_value (EnumValue ev) { + if (internal_scope) { + return; + } + + write_indent (); + write_identifier (ev.name); + write_string (","); + write_newline (); + } + + public override void visit_constant (Constant c) { + } + + public override void visit_field (Field f) { + if (internal_scope || f.access != MemberAccessibility.PUBLIC) { + return; + } + + write_indent (); + write_string ("public "); + write_string (f.type_reference.type.symbol.get_full_name ()); + write_string (" "); + write_identifier (f.name); + write_string (";"); + write_newline (); + } + + public override void visit_begin_method (Method m) { + if (internal_scope || m.access != MemberAccessibility.PUBLIC || m.is_override) { + return; + } + + write_indent (); + write_string ("public "); + + if (!m.instance) { + write_string ("static "); + } else if (m.is_abstract) { + write_string ("abstract "); + } else if (m.is_virtual) { + write_string ("virtual "); + } + + var type = m.return_type.type; + if (type == null) { + write_string ("void"); + } else { + write_string (m.return_type.type.symbol.get_full_name ()); + } + + write_string (" "); + write_identifier (m.name); + write_string (" ("); + + bool first = true; + foreach (FormalParameter param in m.parameters) { + if (!first) { + write_string (", "); + } else { + first = false; + } + + write_string (param.type_reference.type.symbol.get_full_name ()); + write_string (" "); + write_identifier (param.name); + } + + write_string (");"); + write_newline (); + } + + public override void visit_begin_property (Property prop) { + if (internal_scope) { + return; + } + + write_indent (); + write_string ("public "); + write_string (prop.type_reference.type.symbol.get_full_name ()); + write_string (" "); + write_identifier (prop.name); + write_string (" { get; set construct; }"); + write_newline (); + } + + private void write_indent () { + int i; + + if (!bol) { + stream.putc ('\n'); + } + + for (i = 0; i < indent; i++) { + stream.putc ('\t'); + } + + bol = false; + } + + private void write_identifier (string s) { + if (s.collate ("namespace") == 0) { + stream.putc ('@'); + } + write_string (s); + } + + private void write_string (string s) { + stream.printf ("%s", s); + bol = false; + } + + private void write_newline () { + stream.putc ('\n'); + bol = true; + } + + private void write_begin_block () { + if (!bol) { + stream.putc (' '); + } else { + write_indent (); + } + stream.putc ('{'); + write_newline (); + indent++; + } + + private void write_end_block () { + indent--; + write_indent (); + stream.printf ("}"); + } + } +} diff --git a/vala/vala/valamemberaccessibility.vala b/vala/vala/valamemberaccessibility.vala index 00939a9..a9c39db 100644 --- a/vala/vala/valamemberaccessibility.vala +++ b/vala/vala/valamemberaccessibility.vala @@ -25,6 +25,7 @@ using GLib; namespace Vala { public enum MemberAccessibility { PRIVATE, + INTERNAL, PUBLIC } } diff --git a/vala/vala/valamethod.vala b/vala/vala/valamethod.vala index b564665..ab07d06 100644 --- a/vala/vala/valamethod.vala +++ b/vala/vala/valamethod.vala @@ -41,14 +41,12 @@ namespace Vala { public bool is_abstract; public bool is_virtual; public bool is_override; - List parameters; + public List parameters; public string cname; public bool returns_modified_pointer; public bool instance_last; public Method base_method; - Symbol dummy_symbol; // dummy type reference for broken dependency handling - public static ref Method new (string name, TypeReference return_type, SourceReference source) { return (new Method (name = name, return_type = return_type, source_reference = source)); } @@ -85,7 +83,7 @@ namespace Vala { } else if (parent is Namespace) { cname = "%s%s".printf (((Namespace) parent).get_lower_case_cprefix (), name); } else { - stderr.printf ("internal error: method is neither in struct nor in namespace\n"); + Report.error (source_reference, "method is neither in struct nor in namespace\n"); } } return cname; diff --git a/vala/vala/valaproperty.vala b/vala/vala/valaproperty.vala index ba508b5..205f346 100644 --- a/vala/vala/valaproperty.vala +++ b/vala/vala/valaproperty.vala @@ -31,8 +31,6 @@ namespace Vala { public SourceReference source_reference { get; construct; } public MemberAccessibility access; - Symbol dummy_symbol; // dummy variable due to broken depndency handling - public static ref Property new (string name, TypeReference type, PropertyAccessor get_accessor, PropertyAccessor set_accessor, SourceReference source) { return (new Property (name = name, type_reference = type, get_accessor = get_accessor, set_accessor = set_accessor, source_reference = source)); } diff --git a/vala/vala/valareport.vala b/vala/vala/valareport.vala new file mode 100644 index 0000000..83a898c --- /dev/null +++ b/vala/vala/valareport.vala @@ -0,0 +1,56 @@ +/* valareport.vala + * + * Copyright (C) 2006 Jürg Billeter + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: + * Jürg Billeter + */ + +using GLib; + +namespace Vala { + public class Report { + static int warnings; + static int errors; + + public static int get_warnings () { + return warnings; + } + + public static int get_errors () { + return errors; + } + + public static void warning (SourceReference source, string message) { + warnings++; + if (source == null) { + stderr.printf ("warning: %s\n", message); + } else { + stderr.printf ("%s: warning: %s\n", source.to_string (), message); + } + } + + public static void error (SourceReference source, string message) { + errors++; + if (source == null) { + stderr.printf ("error: %s\n", message); + } else { + stderr.printf ("%s: error: %s\n", source.to_string (), message); + } + } + } +} diff --git a/vala/vala/valasemanticanalyzer.vala b/vala/vala/valasemanticanalyzer.vala index 9462ce2..1393676 100644 --- a/vala/vala/valasemanticanalyzer.vala +++ b/vala/vala/valasemanticanalyzer.vala @@ -29,7 +29,6 @@ namespace Vala { SourceFile current_source_file; List current_using_directives; - TypeReference dummy; // required for broken dependency handlind public void analyze (CodeContext context) { root_symbol = context.root; @@ -115,18 +114,21 @@ namespace Vala { } } if (m.base_method == null) { - stderr.printf ("No virtual or abstract method found to override.\n"); + Report.error (m.source_reference, "%s: no suitable method found to override".printf (m.symbol.get_full_name ())); } - } else { - stderr.printf ("Overriding only allowed in classes.\n"); + } else if (current_symbol.node is Struct) { + Report.error (m.source_reference, "A struct member `%s' cannot be marked as override, virtual, or abstract".printf (m.symbol.get_full_name ())); + return; } } } public override void visit_formal_parameter (FormalParameter p) { - if (p.type_reference.type != null) { - /* is null if it references a type parameter */ - current_source_file.add_symbol_dependency (p.type_reference.type.symbol, SourceFileDependencyType.HEADER_SHALLOW); + if (!p.ellipsis) { + if (p.type_reference.type != null) { + /* is null if it references a type parameter */ + current_source_file.add_symbol_dependency (p.type_reference.type.symbol, SourceFileDependencyType.HEADER_SHALLOW); + } } } @@ -192,6 +194,7 @@ namespace Vala { } public override void visit_null_literal (NullLiteral expr) { + expr.static_type = new TypeReference (); } public override void visit_literal_expression (LiteralExpression expr) { @@ -202,6 +205,9 @@ namespace Vala { if (node is Field) { var f = (Field) node; return f.type_reference; + } else if (node is Constant) { + var c = (Constant) node; + return c.type_reference; } else if (node is Property) { var prop = (Property) node; return prop.type_reference; @@ -213,6 +219,10 @@ namespace Vala { } else if (node is VariableDeclarator) { var decl = (VariableDeclarator) node; return decl.type_reference; + } else if (node is EnumValue) { + var type = new TypeReference (); + type.type = (Type_) node.symbol.parent_symbol.node; + return type; } return null; } @@ -239,15 +249,16 @@ namespace Vala { foreach (NamespaceReference ns in current_using_directives) { var local_sym = ns.namespace_symbol.lookup (expr.name); if (expr.symbol_reference != null && local_sym != null) { - // raise error - stderr.printf ("ambiguous symbol name %s\n", expr.name); + Report.error (expr.source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (expr.name, expr.symbol_reference.get_full_name (), local_sym.get_full_name ())); + return; } expr.symbol_reference = local_sym; } } if (expr.symbol_reference == null) { - stderr.printf ("symbol ´%s´ not found\n", expr.name); + Report.error (expr.source_reference, "The name `%s' does not exist in the context of `%s'".printf (expr.name, current_symbol.get_full_name ())); + return; } current_source_file.add_symbol_dependency (expr.symbol_reference, SourceFileDependencyType.SOURCE); @@ -266,22 +277,105 @@ namespace Vala { } } - if (expr.symbol_reference == null) { + if (expr.symbol_reference == null && expr.inner.static_type != null) { expr.symbol_reference = symbol_lookup_inherited (expr.inner.static_type.type.symbol, expr.member_name); } if (expr.symbol_reference == null) { - stderr.printf ("%s: member ´%s´ not found\n", expr.source_reference.to_string (), expr.member_name); + if (expr.inner.static_type == null) { + Report.error (expr.source_reference, "The name `%s' does not exist in the context of `%s'".printf (expr.member_name, expr.inner.symbol_reference.get_full_name ())); + } else { + Report.error (expr.source_reference, "The name `%s' does not exist in the context of `%s'".printf (expr.member_name, expr.inner.static_type.type.symbol.get_full_name ())); + } + return; } current_source_file.add_symbol_dependency (expr.symbol_reference, SourceFileDependencyType.SOURCE); expr.static_type = get_static_type_for_node (expr.symbol_reference.node); } + + private bool is_type_compatible (TypeReference expression_type, TypeReference expected_type) { + /* null can be casted to any reference or array type */ + if (expression_type.type == null && (expected_type.type.is_reference_type () || expected_type.array)) { + return true; + } + + /* temporarily ignore type parameters */ + if (expected_type.type_parameter != null) { + return true; + } + + if (expression_type.array != expected_type.array) { + return false; + } + + if (expression_type.type == expected_type.type) { + return true; + } + + /* int may be implicitly casted to long */ + if (expression_type.type == root_symbol.lookup ("int").node && expected_type.type == root_symbol.lookup ("long").node) { + return true; + } + + /* int may be implicitly casted to long */ + if (expression_type.type == root_symbol.lookup ("char").node && expected_type.type == root_symbol.lookup ("unichar").node) { + return true; + } + + /* non-class types must match exactly */ + if (!(expression_type.type is Class)) { + return false; + } + + var cl = (Class) expression_type.type; + + var base_class = cl.base_class; + for (; base_class != null; base_class = base_class.base_class) { + if (base_class == expected_type) { + return true; + } + } + + return true; + } public override void visit_invocation_expression (InvocationExpression expr) { var m = (Method) expr.call.symbol_reference.node; expr.static_type = m.return_type; + + List arg_it = expr.argument_list; + + bool ellipsis = false; + int i = 0; + foreach (FormalParameter param in m.parameters) { + if (param.ellipsis) { + ellipsis = true; + break; + } + + if (arg_it == null) { + /* if (param.default_argument) { } */ + Report.error (expr.source_reference, "Method `%s' does not take %d arguments".printf (m.symbol.get_full_name (), expr.argument_list.length ())); + return; + } + + var arg = (Expression) arg_it.data; + if (!is_type_compatible (arg.static_type, param.type_reference)) { + Report.warning (expr.source_reference, "Argument %d: Cannot convert from `%s' to `%s'".printf (i + 1, arg.static_type.type.symbol.get_full_name (), param.type_reference.type.symbol.get_full_name ())); + return; + } + + arg_it = arg_it.next; + + i++; + } + + if (!ellipsis && arg_it != null) { + Report.warning (expr.source_reference, "Method `%s' does not take %d arguments".printf (m.symbol.get_full_name (), expr.argument_list.length ())); + return; + } } public override void visit_object_creation_expression (ObjectCreationExpression expr) { @@ -290,12 +384,20 @@ namespace Vala { expr.static_type = expr.type_reference; } + public override void visit_unary_expression (UnaryExpression expr) { + expr.static_type = expr.inner.static_type; + } + public override void visit_cast_expression (CastExpression expr) { current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE); expr.static_type = expr.type_reference; } + public override void visit_binary_expression (BinaryExpression expr) { + expr.static_type = expr.left.static_type; + } + public override void visit_type_check (TypeCheck expr) { current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE); diff --git a/vala/vala/valasourcefile.vala b/vala/vala/valasourcefile.vala index c783ad6..4806fd1 100644 --- a/vala/vala/valasourcefile.vala +++ b/vala/vala/valasourcefile.vala @@ -33,8 +33,6 @@ namespace Vala { Namespace global_namespace; List namespaces; - TypeReference dummy_type_reference; // dummy type reference due to broken dependency handling - private void init () { global_namespace = new Namespace (source_reference = new SourceReference (file = this)); } @@ -110,12 +108,14 @@ namespace Vala { if (sym.node is Type_) { t = (Type_) sym.node; - } else if (sym.node is Method) { + } else if (sym.node is Method || sym.node is Field) { if (sym.parent_symbol.node is Type_) { t = (Type_) sym.parent_symbol.node; } else { return; } + } else if (sym.node is Property) { + t = (Type_) sym.parent_symbol.node; } else if (sym.node is FormalParameter) { var fp = (FormalParameter) sym.node; t = fp.type_reference.type; diff --git a/vala/vala/valasymbol.vala b/vala/vala/valasymbol.vala index 0cac214..c3aa7d6 100644 --- a/vala/vala/valasymbol.vala +++ b/vala/vala/valasymbol.vala @@ -27,10 +27,28 @@ namespace Vala { HashTable symbol_table = HashTable.new (str_hash, str_equal); public CodeNode node { get; construct; } public weak Symbol parent_symbol; + public string name; + + public ref string get_full_name () { + if (parent_symbol == null) { + return name; + } + + if (name == null) { + return parent_symbol.get_full_name (); + } + + if (parent_symbol.get_full_name () == null) { + return name; + } + + return "%s.%s".printf (parent_symbol.get_full_name (), name); + } public void add (string s, Symbol sym) { symbol_table.insert (s, sym); sym.parent_symbol = this; + sym.name = s; } public Symbol lookup (string s) { diff --git a/vala/vala/valasymbolbuilder.vala b/vala/vala/valasymbolbuilder.vala index b2c9915..96e8290 100644 --- a/vala/vala/valasymbolbuilder.vala +++ b/vala/vala/valasymbolbuilder.vala @@ -54,8 +54,7 @@ namespace Vala { public override void visit_begin_class (Class cl) { if (cl.@namespace.symbol.lookup (cl.name) != null) { - // TODO: raise error - stderr.printf ("symbol conflict %s\n", cl.name); + Report.error (cl.source_reference, "The namespace `%s' already contains a definition for `%s'".printf (cl.@namespace.symbol.get_full_name (), cl.name)); return; } cl.symbol = new Symbol (node = cl); @@ -70,8 +69,7 @@ namespace Vala { public override void visit_begin_struct (Struct st) { if (st.@namespace.symbol.lookup (st.name) != null) { - // TODO: raise error - stderr.printf ("symbol conflict %s\n", st.name); + Report.error (st.source_reference, "The namespace `%s' already contains a definition for `%s'".printf (st.@namespace.symbol.get_full_name (), st.name)); return; } st.symbol = new Symbol (node = st); @@ -86,8 +84,7 @@ namespace Vala { public override void visit_begin_enum (Enum en) { if (en.@namespace.symbol.lookup (en.name) != null) { - // TODO: raise error - stderr.printf ("symbol conflict\n"); + Report.error (en.source_reference, "The namespace `%s' already contains a definition for `%s'".printf (en.@namespace.symbol.get_full_name (), en.name)); return; } en.symbol = new Symbol (node = en); @@ -106,8 +103,7 @@ namespace Vala { public override void visit_constant (Constant c) { if (current_symbol.lookup (c.name) != null) { - // TODO: raise error - stderr.printf ("symbol conflict\n"); + Report.error (c.source_reference, "The type `%s' already contains a definition for `%s'".printf (current_symbol.get_full_name (), c.name)); return; } c.symbol = new Symbol (node = c); @@ -116,8 +112,7 @@ namespace Vala { public override void visit_field (Field f) { if (current_symbol.lookup (f.name) != null) { - // TODO: raise error - stderr.printf ("%s: symbol conflict %s\n", f.source_reference.to_string (), f.name); + Report.error (f.source_reference, "The type `%s' already contains a definition for `%s'".printf (current_symbol.get_full_name (), f.name)); return; } f.symbol = new Symbol (node = f); @@ -126,8 +121,7 @@ namespace Vala { public override void visit_begin_method (Method m) { if (current_symbol.lookup (m.name) != null) { - // TODO: raise error - stderr.printf ("symbol conflict\n"); + Report.error (m.source_reference, "The type `%s' already contains a definition for `%s'".printf (current_symbol.get_full_name (), m.name)); return; } m.symbol = new Symbol (node = m); @@ -146,14 +140,15 @@ namespace Vala { } public override void visit_formal_parameter (FormalParameter p) { - p.symbol = new Symbol (node = p); - current_symbol.add (p.name, p.symbol); + if (!p.ellipsis) { + p.symbol = new Symbol (node = p); + current_symbol.add (p.name, p.symbol); + } } public override void visit_begin_property (Property prop) { if (current_symbol.lookup (prop.name) != null) { - // TODO: raise error - stderr.printf ("symbol conflict\n"); + Report.error (prop.source_reference, "The type `%s' already contains a definition for `%s'".printf (current_symbol.get_full_name (), prop.name)); return; } prop.symbol = new Symbol (node = prop); @@ -209,8 +204,7 @@ namespace Vala { public override void visit_type_parameter (TypeParameter p) { if (p.type.symbol.lookup (p.name) != null) { - // TODO: raise error - stderr.printf ("symbol conflict\n"); + Report.error (p.source_reference, "The method `%s' already has a parameter named `%s'".printf (current_symbol.get_full_name (), p.name)); return; } p.symbol = new Symbol (node = p); diff --git a/vala/vala/valasymbolresolver.vala b/vala/vala/valasymbolresolver.vala index 2676ca8..18880a9 100644 --- a/vala/vala/valasymbolresolver.vala +++ b/vala/vala/valasymbolresolver.vala @@ -58,7 +58,8 @@ namespace Vala { foreach (TypeReference type in cl.base_types) { if (type.type is Class) { if (cl.base_class != null) { - stderr.printf ("error: multiple base classes specified\n"); + Report.error (type.source_reference, "%s: Classes cannot have multiple base classes (`%s' and `%s')".printf (cl.symbol.get_full_name (), cl.base_class.symbol.get_full_name (), type.type.symbol.get_full_name ())); + return; } cl.base_class = type.type; } @@ -81,8 +82,8 @@ namespace Vala { public override void visit_namespace_reference (NamespaceReference ns) { ns.namespace_symbol = current_scope.lookup (ns.name); if (ns.namespace_symbol == null) { - // raise error, namespace not found - stderr.printf ("namespace %s not found\n", ns.name); + Report.error (ns.source_reference, "The namespace name `%s' could not be found".printf (ns.name)); + return; } } @@ -102,15 +103,15 @@ namespace Vala { foreach (NamespaceReference ns in current_using_directives) { var local_sym = ns.namespace_symbol.lookup (type.type_name); if (sym != null && local_sym != null) { - // raise error - stderr.printf ("error: ambiguous type name %s\n", type.type_name); + Report.error (type.source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (type.type_name, sym.get_full_name (), local_sym.get_full_name ())); + return; } sym = local_sym; } } if (sym == null) { - // raise error, type not found - stderr.printf ("error: type %s not found\n", type.type_name); + Report.error (type.source_reference, "The type name `%s' could not be found".printf (type.type_name)); + return; } if (sym.node is TypeParameter) { type.type_parameter = sym.node; @@ -120,14 +121,14 @@ namespace Vala { } else { var ns_symbol = root_symbol.lookup (type.namespace_name); if (ns_symbol == null) { - // raise error - stderr.printf ("error: namespace ´%s´ not found\n", type.namespace_name); + Report.error (type.source_reference, "The namespace name `%s' could not be found".printf (type.namespace_name)); + return; } var sym = ns_symbol.lookup (type.type_name); if (sym == null) { - // raise error - stderr.printf ("error: symbol ´%s´ not found in namespace ´%s´\n", type.type_name, type.namespace_name); + Report.error (type.source_reference, "The type name `%s' does not exist in the namespace `%s'".printf (type.type_name, type.namespace_name)); + return; } type.type = (Type_) sym.node; } diff --git a/vala/vala/valatype.vala b/vala/vala/valatype.vala index 66b0361..6c8e71b 100644 --- a/vala/vala/valatype.vala +++ b/vala/vala/valatype.vala @@ -27,6 +27,7 @@ namespace Vala { public string name { get; construct; } public SourceReference source_reference { get; construct; } public Namespace @namespace; + public MemberAccessibility access; public abstract string get_cname (); public abstract bool is_reference_type (); diff --git a/vala/vala/valatypereference.vala b/vala/vala/valatypereference.vala index 6f69500..edf8dc1 100644 --- a/vala/vala/valatypereference.vala +++ b/vala/vala/valatypereference.vala @@ -115,7 +115,7 @@ namespace Vala { return "gpointer".concat (ptr, arr, null); } else { /* raise error */ - stderr.printf ("error: unresolved type reference\n"); + Report.error (source_reference, "unresolved type reference"); return null; } } diff --git a/vala/valac/Makefile.am b/vala/valac/Makefile.am deleted file mode 100644 index e4f66e0..0000000 --- a/vala/valac/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -NULL = - -INCLUDES = \ - $(GLIB_CFLAGS) \ - $(NULL) - -BUILT_SOURCES = parser.h -AM_YFLAGS = -d - -bin_PROGRAMS = \ - valac \ - $(NULL) - -valac_SOURCES = \ - driver.c \ - parser.y \ - scanner.l \ - context.c \ - generator.c \ - $(NULL) - -valac_LDADD = \ - $(GLIB_LIBS) \ - $(NULL) diff --git a/vala/valac/context.c b/vala/valac/context.c deleted file mode 100644 index 51164da..0000000 --- a/vala/valac/context.c +++ /dev/null @@ -1,717 +0,0 @@ -/* context.c - * - * Copyright (C) 2006 Jürg Billeter, Raffaele Sandrini - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: - * Jürg Billeter - * Raffaele Sandrini - */ - -#include -#include -#include - -#include - -#include "context.h" - -ValaContext * -vala_context_new () -{ - return g_new0 (ValaContext, 1); -} - -void -vala_context_free (ValaContext *context) -{ - g_free (context); -} - -void -vala_context_parse (ValaContext *context) -{ - GList *l; - for (l = context->source_files; l != NULL; l = l->next) { - vala_parser_parse (l->data); - } -} - -ValaSymbol * -vala_symbol_new (ValaSymbolType type) -{ - ValaSymbol *symbol; - symbol = g_new0 (ValaSymbol, 1); - symbol->type = type; - symbol->symbol_table = g_hash_table_new (g_str_hash, g_str_equal); - return symbol; -} - -void -err (ValaLocation *location, const char *format, ...) -{ - va_list args; - va_start (args, format); - if (location != NULL) { - fprintf (stderr, "%s:%d:%d: ", location->source_file->filename, location->lineno, location->colno); - } - vfprintf (stderr, format, args); - fprintf (stderr, "\n"); - va_end (args); - exit (1); -} - -static void -vala_context_add_symbols_from_constant (ValaContext *context, ValaSymbol *class_symbol, ValaConstant *constant) -{ - ValaSymbol *constant_symbol; - char *name = constant->declaration_statement->variable_declaration->declarator->name; - - constant_symbol = g_hash_table_lookup (class_symbol->symbol_table, name); - if (constant_symbol != NULL) { - err (constant->declaration_statement->variable_declaration->declarator->location, "error: class member ´%s.%s.%s´ already defined", class_symbol->class->namespace->name, class_symbol->class->name, name); - } - - constant_symbol = vala_symbol_new (VALA_SYMBOL_TYPE_CONSTANT); - constant_symbol->constant = constant; - constant->symbol = constant_symbol; - g_hash_table_insert (class_symbol->symbol_table, name, constant_symbol); -} - -static void -vala_context_add_symbols_from_method (ValaContext *context, ValaSymbol *class_symbol, ValaMethod *method) -{ - method->symbol = g_hash_table_lookup (class_symbol->symbol_table, method->name); - if (method->symbol != NULL) { - err (method->location, "error: class member ´%s.%s.%s´ already defined", class_symbol->class->namespace->name, class_symbol->class->name, method->name); - } - - method->symbol = vala_symbol_new (VALA_SYMBOL_TYPE_METHOD); - method->symbol->method = method; - g_hash_table_insert (class_symbol->symbol_table, method->name, method->symbol); - - if (method->body != NULL) { - method->body->method = method->symbol; - } -} - -static void -vala_context_add_symbols_from_field (ValaContext *context, ValaSymbol *class_symbol, ValaField *field) -{ - ValaSymbol *field_symbol; - char *name = field->declaration_statement->variable_declaration->declarator->name; - - field_symbol = g_hash_table_lookup (class_symbol->symbol_table, name); - if (field_symbol != NULL) { - err (field->declaration_statement->variable_declaration->declarator->location, "error: class member ´%s.%s.%s´ already defined", class_symbol->class->namespace->name, class_symbol->class->name, name); - } - - field_symbol = vala_symbol_new (VALA_SYMBOL_TYPE_FIELD); - field_symbol->field = field; - field->symbol = field_symbol; - g_hash_table_insert (class_symbol->symbol_table, name, field_symbol); -} - -static void -vala_context_add_symbols_from_property (ValaContext *context, ValaSymbol *class_symbol, ValaProperty *property) -{ - ValaSymbol *property_symbol; - - property_symbol = g_hash_table_lookup (class_symbol->symbol_table, property->name); - if (property_symbol != NULL) { - err (property->location, "error: class member ´%s.%s.%s´ already defined", class_symbol->class->namespace->name, class_symbol->class->name, property->name); - } - - property_symbol = vala_symbol_new (VALA_SYMBOL_TYPE_PROPERTY); - property_symbol->property = property; - property->symbol = property_symbol; - g_hash_table_insert (class_symbol->symbol_table, property->name, property_symbol); -} - -static void -vala_context_add_symbols_from_class (ValaContext *context, ValaClass *class) -{ - ValaSymbol *ns_symbol, *class_symbol; - ns_symbol = class->namespace->symbol; - GList *l; - - class_symbol = g_hash_table_lookup (ns_symbol->symbol_table, class->name); - if (class_symbol != NULL) { - err (class->location, "error: class ´%s.%s´ already defined", class->namespace->name, class->name); - } - - class_symbol = vala_symbol_new (VALA_SYMBOL_TYPE_CLASS); - class_symbol->class = class; - g_hash_table_insert (ns_symbol->symbol_table, class->name, class_symbol); - - class->symbol = class_symbol; - - for (l = class->constants; l != NULL; l = l->next) { - vala_context_add_symbols_from_constant (context, class_symbol, l->data); - } - - for (l = class->methods; l != NULL; l = l->next) { - vala_context_add_symbols_from_method (context, class_symbol, l->data); - } - - for (l = class->fields; l != NULL; l = l->next) { - vala_context_add_symbols_from_field (context, class_symbol, l->data); - } - - for (l = class->properties; l != NULL; l = l->next) { - vala_context_add_symbols_from_property (context, class_symbol, l->data); - } -} - -static void -vala_context_add_symbols_from_struct (ValaContext *context, ValaStruct *struct_) -{ - ValaSymbol *ns_symbol, *struct_symbol; - ns_symbol = struct_->namespace->symbol; - GList *ml, *l; - - struct_symbol = g_hash_table_lookup (ns_symbol->symbol_table, struct_->name); - if (struct_symbol != NULL) { - err (struct_->location, "error: struct ´%s.%s´ already defined", struct_->namespace->name, struct_->name); - } - - struct_symbol = vala_symbol_new (VALA_SYMBOL_TYPE_STRUCT); - struct_symbol->struct_ = struct_; - g_hash_table_insert (ns_symbol->symbol_table, struct_->name, struct_symbol); - - struct_->symbol = struct_symbol; - - for (l = struct_->methods; l != NULL; l = l->next) { - vala_context_add_symbols_from_method (context, struct_symbol, l->data); - } - - for (l = struct_->fields; l != NULL; l = l->next) { - vala_context_add_symbols_from_field (context, struct_symbol, l->data); - } -} - -static void -vala_context_add_symbols_from_enum (ValaContext *context, ValaEnum *enum_) -{ - ValaSymbol *ns_symbol, *enum_symbol; - ns_symbol = enum_->namespace->symbol; - GList *l; - - enum_symbol = g_hash_table_lookup (ns_symbol->symbol_table, enum_->name); - if (enum_symbol != NULL) { - err (enum_->location, "error: enum ´%s.%s´ already defined", enum_->namespace->name, enum_->name); - } - - enum_symbol = vala_symbol_new (VALA_SYMBOL_TYPE_ENUM); - enum_symbol->enum_ = enum_; - g_hash_table_insert (ns_symbol->symbol_table, enum_->name, enum_symbol); - - enum_->symbol = enum_symbol; - - for (l = enum_->values; l != NULL; l = l->next) { - ValaSymbol *value_symbol; - ValaEnumValue *value = l->data; - - value_symbol = g_hash_table_lookup (enum_symbol->symbol_table, value->name); - if (value_symbol != NULL) { - err (enum_->location, "error: enum member ´%s.%s.%s´ already defined", enum_->namespace->name, enum_->name, value->name); - } - - value_symbol = vala_symbol_new (VALA_SYMBOL_TYPE_ENUM_VALUE); - value_symbol->enum_value = value; - value->symbol = value_symbol; - g_hash_table_insert (enum_symbol->symbol_table, value->name, value_symbol); - } -} - -static void -vala_context_add_symbols_from_namespace (ValaContext *context, ValaNamespace *namespace) -{ - ValaSymbol *ns_symbol, *class_symbol; - GList *cl; - - if (strlen (namespace->name) == 0) { - ns_symbol = context->root; - } else { - ns_symbol = g_hash_table_lookup (context->root->symbol_table, namespace->name); - if (ns_symbol == NULL) { - ns_symbol = vala_symbol_new (VALA_SYMBOL_TYPE_NAMESPACE); - g_hash_table_insert (context->root->symbol_table, namespace->name, ns_symbol); - } - } - - namespace->symbol = ns_symbol; - - for (cl = namespace->classes; cl != NULL; cl = cl->next) { - vala_context_add_symbols_from_class (context, cl->data); - } - - for (cl = namespace->structs; cl != NULL; cl = cl->next) { - vala_context_add_symbols_from_struct (context, cl->data); - } - - for (cl = namespace->enums; cl != NULL; cl = cl->next) { - vala_context_add_symbols_from_enum (context, cl->data); - } - - for (cl = namespace->fields; cl != NULL; cl = cl->next) { - vala_context_add_symbols_from_field (context, ns_symbol, cl->data); - } - - for (cl = namespace->methods; cl != NULL; cl = cl->next) { - vala_context_add_symbols_from_method (context, ns_symbol, cl->data); - } -} - -void -vala_context_add_fundamental_symbols (ValaContext *context) -{ - ValaSymbol *symbol; - ValaNamespace *namespace; - ValaClass *class; - ValaStruct *struct_; - ValaEnum *enum_; - ValaMethod *method; - ValaEnumValue *enum_value; - ValaField *field; - - context->root = vala_symbol_new (VALA_SYMBOL_TYPE_ROOT); - - namespace = g_new0 (ValaNamespace, 1); - namespace->name = g_strdup (""); - namespace->lower_case_cname = g_strdup (""); - namespace->upper_case_cname = g_strdup (""); - - /* void */ - symbol = vala_symbol_new (VALA_SYMBOL_TYPE_VOID); - g_hash_table_insert (context->root->symbol_table, "void", symbol); - - vala_context_add_symbols_from_namespace (context, namespace); -} - -void -vala_context_add_alias (ValaContext *context) -{ - /* Add alias object = GLib.Object */ - ValaSymbol *symbol = g_hash_table_lookup (context->root->symbol_table, "GLib"); - if (symbol != NULL) { - symbol = g_hash_table_lookup (symbol->symbol_table, "Object"); - if (symbol != NULL) { - g_hash_table_insert (context->root->symbol_table, "object", symbol); - } - } -} - -void -vala_context_add_symbols_from_source_files (ValaContext *context) -{ - GList *fl; - - for (fl = context->source_files; fl != NULL; fl = fl->next) { - ValaSourceFile *source_file = fl->data; - GList *nsl; - - vala_context_add_symbols_from_namespace (context, source_file->root_namespace); - for (nsl = source_file->namespaces; nsl != NULL; nsl = nsl->next) { - vala_context_add_symbols_from_namespace (context, nsl->data); - } - } -} - -static void -vala_context_resolve_type_reference (ValaContext *context, ValaNamespace *namespace, GList *type_parameter_list, ValaTypeReference *type_reference) -{ - ValaSymbol *type_symbol = NULL, *ns_symbol; - GList *l; - - type_reference->type_param_index = -1; - - if (type_reference->type_name == NULL) { - /* var type, resolve on initialization */ - return; - } else if (type_reference->namespace_name == NULL || strlen (type_reference->namespace_name) == 0) { - /* no namespace specified */ - - /* check for generic type parameter */ - int i; - for (i = 0, l = type_parameter_list; l != NULL; i++, l = l->next) { - if (strcmp (l->data, type_reference->type_name) == 0) { - type_reference->type_param_index = i; - type_symbol = g_hash_table_lookup (context->root->symbol_table, "pointer"); - break; - } - } - - if (type_symbol == NULL && namespace != NULL) { - /* look in current namespace */ - type_symbol = g_hash_table_lookup (namespace->symbol->symbol_table, type_reference->type_name); - if (type_symbol != NULL) { - type_reference->namespace_name = namespace->name; - } - } - - if (type_symbol == NULL) { - /* look in root namespace */ - type_symbol = g_hash_table_lookup (context->root->symbol_table, type_reference->type_name); - if (type_symbol != NULL) { - type_reference->namespace_name = ""; - } - } - - if (type_symbol == NULL && namespace != NULL) { - /* look in namespaces specified by using directives */ - for (l = namespace->source_file->using_directives; l != NULL; l = l->next) { - char *ns = l->data; - ns_symbol = g_hash_table_lookup (context->root->symbol_table, ns); - if (ns_symbol == NULL) { - err (type_reference->location, "error: specified namespace ´%s´ not found", ns); - } - type_symbol = g_hash_table_lookup (ns_symbol->symbol_table, type_reference->type_name); - if (type_symbol != NULL) { - type_reference->namespace_name = ns; - break; - } - } - } - - if (type_symbol == NULL) { - /* specified namespace not found */ - err (type_reference->location, "error: specified type ´%s´ not found", type_reference->type_name); - } - } else { - /* namespace has been explicitly specified */ - ns_symbol = g_hash_table_lookup (context->root->symbol_table, type_reference->namespace_name); - if (ns_symbol == NULL) { - /* specified namespace not found */ - err (type_reference->location, "error: specified namespace '%s' not found (type ´%s´)", type_reference->namespace_name, type_reference->type_name); - } - - type_symbol = g_hash_table_lookup (ns_symbol->symbol_table, type_reference->type_name); - if (type_symbol == NULL) { - /* specified namespace not found */ - err (type_reference->location, "error: specified type ´%s´ not found in namespace ´%s´", type_reference->type_name, type_reference->namespace_name); - } - } - - if (type_symbol->type == VALA_SYMBOL_TYPE_VOID || - type_symbol->type == VALA_SYMBOL_TYPE_CLASS || - type_symbol->type == VALA_SYMBOL_TYPE_ENUM || - type_symbol->type == VALA_SYMBOL_TYPE_STRUCT) { - type_reference->symbol = type_symbol; - if (type_symbol->type != VALA_SYMBOL_TYPE_VOID && namespace != NULL && namespace->source_file != NULL) { - namespace->source_file->dep_types = g_list_prepend (namespace->source_file->dep_types, type_symbol); - } - } else { - err (type_reference->location, "error: specified symbol ´%s´ is not a type", type_reference->type_name); - } -} - -static void vala_context_resolve_types_in_block (ValaContext *context, ValaNamespace *namespace, ValaStatement *stmt); - -static void -vala_context_resolve_types_in_expression (ValaContext *context, ValaNamespace *namespace, ValaExpression *expr) -{ - GList *l; - - switch (expr->type) { - case VALA_EXPRESSION_TYPE_ASSIGNMENT: - vala_context_resolve_types_in_expression (context, namespace, expr->assignment.right); - break; - case VALA_EXPRESSION_TYPE_CAST: - vala_context_resolve_type_reference (context, namespace, NULL, expr->cast.type); - break; - case VALA_EXPRESSION_TYPE_INVOCATION: - vala_context_resolve_types_in_expression (context, namespace, expr->invocation.call); - for (l = expr->invocation.argument_list; l != NULL; l = l->next) { - vala_context_resolve_types_in_expression (context, namespace, l->data); - } - break; - case VALA_EXPRESSION_TYPE_IS: - vala_context_resolve_type_reference (context, namespace, NULL, expr->is.type); - break; - case VALA_EXPRESSION_TYPE_MEMBER_ACCESS: - vala_context_resolve_types_in_expression (context, namespace, expr->member_access.left); - break; - case VALA_EXPRESSION_TYPE_OPERATION: - if (expr->op.left != NULL) { - vala_context_resolve_types_in_expression (context, namespace, expr->op.left); - } - if (expr->op.right != NULL) { - vala_context_resolve_types_in_expression (context, namespace, expr->op.right); - } - break; - case VALA_EXPRESSION_TYPE_OBJECT_CREATION: - vala_context_resolve_type_reference (context, namespace, NULL, expr->object_creation.type); - for (l = expr->object_creation.named_argument_list; l != NULL; l = l->next) { - ValaNamedArgument *na = l->data; - vala_context_resolve_types_in_expression (context, namespace, na->expression); - } - break; - case VALA_EXPRESSION_TYPE_PARENTHESIZED: - vala_context_resolve_types_in_expression (context, namespace, expr->inner); - break; - } -} - -static void -vala_context_resolve_types_in_statement (ValaContext *context, ValaNamespace *namespace, GList *type_parameters, ValaStatement *stmt) -{ - switch (stmt->type) { - case VALA_STATEMENT_TYPE_VARIABLE_DECLARATION: - vala_context_resolve_type_reference (context, namespace, type_parameters, stmt->variable_declaration->type); - if (stmt->variable_declaration->declarator->initializer != NULL) { - vala_context_resolve_types_in_expression (context, namespace, stmt->variable_declaration->declarator->initializer); - } - break; - case VALA_STATEMENT_TYPE_BLOCK: - vala_context_resolve_types_in_block (context, namespace, stmt); - break; - case VALA_STATEMENT_TYPE_EXPRESSION: - vala_context_resolve_types_in_expression (context, namespace, stmt->expr); - break; - case VALA_STATEMENT_TYPE_IF: - vala_context_resolve_types_in_expression (context, namespace, stmt->if_stmt.condition); - if (stmt->if_stmt.true_stmt != NULL) { - vala_context_resolve_types_in_statement (context, namespace, NULL, stmt->if_stmt.true_stmt); - } - if (stmt->if_stmt.false_stmt != NULL) { - vala_context_resolve_types_in_statement (context, namespace, NULL, stmt->if_stmt.false_stmt); - } - break; - case VALA_STATEMENT_TYPE_WHILE: - vala_context_resolve_types_in_block (context, namespace, stmt->while_stmt.loop); - break; - case VALA_STATEMENT_TYPE_FOR: - vala_context_resolve_types_in_block (context, namespace, stmt->for_stmt.loop); - break; - case VALA_STATEMENT_TYPE_FOREACH: - vala_context_resolve_type_reference (context, namespace, type_parameters, stmt->foreach_stmt.type); - vala_context_resolve_types_in_expression (context, namespace, stmt->foreach_stmt.container); - vala_context_resolve_types_in_block (context, namespace, stmt->foreach_stmt.loop); - break; - case VALA_STATEMENT_TYPE_RETURN: - if (stmt->expr != NULL) { - vala_context_resolve_types_in_expression (context, namespace, stmt->expr); - } - break; - } -} - -static void -vala_context_resolve_types_in_block (ValaContext *context, ValaNamespace *namespace, ValaStatement *stmt) -{ - GList *l; - - for (l = stmt->block.statements; l != NULL; l = l ->next) { - vala_context_resolve_types_in_statement (context, namespace, NULL, l->data); - } -} - -static void -vala_context_resolve_types_in_constant (ValaContext *context, ValaConstant *constant) -{ - vala_context_resolve_types_in_statement (context, constant->class->namespace, NULL, constant->declaration_statement); -} - -static void -vala_context_resolve_types_in_method (ValaContext *context, ValaMethod *method) -{ - GList *l; - ValaNamespace *namespace; - GList *type_parameters; - - if (!method->is_struct_method) { - namespace = method->class->namespace; - type_parameters = method->class->type_parameters; - } else { - namespace = method->struct_->namespace; - type_parameters = method->struct_->type_parameters; - } - - vala_context_resolve_type_reference (context, namespace, type_parameters, method->return_type); - - for (l = method->formal_parameters; l != NULL; l = l->next) { - ValaFormalParameter *formal_parameter = l->data; - - vala_context_resolve_type_reference (context, namespace, type_parameters, formal_parameter->type); - if (formal_parameter->type->symbol->type == VALA_SYMBOL_TYPE_VOID) { - err (formal_parameter->location, "error: method parameters cannot be of type `void`"); - } - } - - if (method->body != NULL) { - vala_context_resolve_types_in_block (context, method->class->namespace, method->body); - } -} - -static void -vala_context_resolve_types_in_field (ValaContext *context, ValaField *field) -{ - ValaNamespace *namespace = NULL; - GList *type_parameters = NULL; - - if (!field->is_struct_field && field->class != NULL) { - namespace = field->class->namespace; - type_parameters = field->class->type_parameters; - } else if (field->struct_ != NULL) { - namespace = field->struct_->namespace; - type_parameters = field->struct_->type_parameters; - } - - vala_context_resolve_types_in_statement (context, namespace, type_parameters, field->declaration_statement); -} - -static void -vala_context_resolve_types_in_property (ValaContext *context, ValaProperty *property) -{ - vala_context_resolve_type_reference (context, property->class->namespace, property->class->type_parameters, property->return_type); - if (property->get_statement != NULL) { - vala_context_resolve_types_in_statement (context, property->class->namespace, NULL, property->get_statement); - } - if (property->set_statement != NULL) { - vala_context_resolve_types_in_statement (context, property->class->namespace, NULL, property->set_statement); - } -} - -static void -vala_context_resolve_types_in_class (ValaContext *context, ValaClass *class) -{ - GList *l; - - for (l = class->base_types; l != NULL; l = l->next) { - ValaTypeReference *type_reference = l->data; - - vala_context_resolve_type_reference (context, class->namespace, NULL, type_reference); - if (type_reference->symbol->type == VALA_SYMBOL_TYPE_CLASS) { - if (class->base_class != NULL) { - err (type_reference->location, "error: more than one base class specified in class ´%s.%s´", class->namespace->name, class->name); - } - class->base_class = type_reference->symbol->class; - if (class->base_class == class) { - err (type_reference->location, "error: ´%s.%s´ cannot be subtype of ´%s.%s´", class->namespace->name, class->name, class->namespace->name, class->name); - } - /* FIXME: check whether base_class is not a subtype of class */ - } else { - err (type_reference->location, "error: ´%s.%s´ cannot be subtype of ´%s.%s´", class->namespace->name, class->name, type_reference->namespace_name, type_reference->type_name); - } - } - - if (class->base_class == NULL) { - ValaSymbol *symbol = g_hash_table_lookup (context->root->symbol_table, "object"); - /* GObject must not have itself as base class */ - if (class != symbol->class) { - class->base_class = symbol->class; - } - } - - for (l = class->constants; l != NULL; l = l->next) { - ValaConstant *constant = l->data; - vala_context_resolve_types_in_constant (context, constant); - } - - for (l = class->methods; l != NULL; l = l->next) { - ValaMethod *method = l->data; - vala_context_resolve_types_in_method (context, method); - } - - for (l = class->fields; l != NULL; l = l->next) { - ValaField *field = l->data; - vala_context_resolve_types_in_field (context, field); - } - - for (l = class->properties; l != NULL; l = l->next) { - ValaProperty *property = l->data; - vala_context_resolve_types_in_property (context, property); - } - -} - -static void -vala_context_resolve_types_in_struct (ValaContext *context, ValaStruct *struct_) -{ - GList *l; - - for (l = struct_->methods; l != NULL; l = l->next) { - ValaMethod *method = l->data; - vala_context_resolve_types_in_method (context, method); - } - - for (l = struct_->fields; l != NULL; l = l->next) { - ValaField *field = l->data; - vala_context_resolve_types_in_field (context, field); - } - -} - -static void -vala_context_resolve_types_in_namespace (ValaContext *context, ValaNamespace *namespace) -{ - GList *cl; - - for (cl = namespace->classes; cl != NULL; cl = cl->next) { - ValaClass *class = cl->data; - - vala_context_resolve_types_in_class (context, class); - } - - for (cl = namespace->structs; cl != NULL; cl = cl->next) { - ValaStruct *struct_ = cl->data; - - vala_context_resolve_types_in_struct (context, struct_); - } - - for (cl = namespace->fields; cl != NULL; cl = cl->next) { - ValaField *field = cl->data; - vala_context_resolve_types_in_field (context, field); - } -} - -void -vala_context_resolve_types (ValaContext *context) -{ - GList *fl; - GList *l; - - for (l = context->imported_namespaces; l != NULL; l = l->next) { - vala_context_resolve_types_in_namespace (context, l->data); - } - - for (fl = context->source_files; fl != NULL; fl = fl->next) { - ValaSourceFile *source_file = fl->data; - GList *nsl; - - vala_context_resolve_types_in_namespace (context, source_file->root_namespace); - for (nsl = source_file->namespaces; nsl != NULL; nsl = nsl->next) { - vala_context_resolve_types_in_namespace (context, nsl->data); - } - } -} - -ValaSourceFile * -vala_source_file_new (const char *filename) -{ - ValaSourceFile *file = g_new0 (ValaSourceFile, 1); - - file->filename = filename; - file->root_namespace = g_new0 (ValaNamespace, 1); - file->root_namespace->name = g_strdup (""); - file->root_namespace->cprefix = g_strdup (""); - file->root_namespace->lower_case_cname = g_strdup (""); - file->root_namespace->upper_case_cname = g_strdup (""); - file->root_namespace->source_file = file; - - return file; -} diff --git a/vala/valac/context.h b/vala/valac/context.h deleted file mode 100644 index 36f1baf..0000000 --- a/vala/valac/context.h +++ /dev/null @@ -1,470 +0,0 @@ -/* context.h - * - * Copyright (C) 2006 Jürg Billeter, Raffaele Sandrini - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: - * Jürg Billeter - * Raffaele Sandrini - */ - -#include - -typedef enum _ValaSymbolType ValaSymbolType; -typedef enum _ValaModifierFlags ValaModifierFlags; -typedef enum _ValaFormalParameterFlags ValaFormalParameterFlags; -typedef enum _ValaStatementType ValaStatementType; -typedef enum _ValaExpressionType ValaExpressionType; -typedef enum _ValaOpType ValaOpType; - -typedef struct _ValaContext ValaContext; -typedef struct _ValaSymbol ValaSymbol; -typedef struct _ValaSourceFile ValaSourceFile; -typedef struct _ValaLocation ValaLocation; -typedef struct _ValaNamespace ValaNamespace; -typedef struct _ValaClass ValaClass; -typedef struct _ValaStruct ValaStruct; -typedef struct _ValaEnum ValaEnum; -typedef struct _ValaFlags ValaFlags; -typedef struct _ValaConstant ValaConstant; -typedef struct _ValaMethod ValaMethod; -typedef struct _ValaField ValaField; -typedef struct _ValaProperty ValaProperty; -typedef struct _ValaEnumValue ValaEnumValue; -typedef struct _ValaFlagsValue ValaFlagsValue; -typedef struct _ValaStatement ValaStatement; -typedef struct _ValaVariableDeclaration ValaVariableDeclaration; -typedef struct _ValaVariableDeclarator ValaVariableDeclarator; -typedef struct _ValaExpression ValaExpression; -typedef struct _ValaTypeReference ValaTypeReference; -typedef struct _ValaFormalParameter ValaFormalParameter; -typedef struct _ValaNamedArgument ValaNamedArgument; -typedef struct _ValaAnnotation ValaAnnotation; - -enum _ValaSymbolType { - VALA_SYMBOL_TYPE_ROOT, - VALA_SYMBOL_TYPE_NAMESPACE, - VALA_SYMBOL_TYPE_VOID, - VALA_SYMBOL_TYPE_CLASS, - VALA_SYMBOL_TYPE_CONSTANT, - VALA_SYMBOL_TYPE_FIELD, - VALA_SYMBOL_TYPE_PROPERTY, - VALA_SYMBOL_TYPE_STRUCT, - VALA_SYMBOL_TYPE_METHOD, - VALA_SYMBOL_TYPE_ENUM, - VALA_SYMBOL_TYPE_ENUM_VALUE, - VALA_SYMBOL_TYPE_BLOCK, - VALA_SYMBOL_TYPE_LOCAL_VARIABLE, -}; - -enum _ValaModifierFlags { - VALA_MODIFIER_PUBLIC = 1 << 0, - VALA_MODIFIER_PRIVATE = 1 << 1, - VALA_MODIFIER_STATIC = 1 << 2, - VALA_MODIFIER_ABSTRACT = 1 << 3, - VALA_MODIFIER_VIRTUAL = 1 << 4, - VALA_MODIFIER_OVERRIDE = 1 << 5, - VALA_MODIFIER_READONLY = 1 << 6, -}; - -enum _ValaFormalParameterFlags { - VALA_FORMAL_PARAMETER_REF = 1 << 0, - VALA_FORMAL_PARAMETER_OUT = 1 << 1, -}; - -enum _ValaStatementType { - VALA_STATEMENT_TYPE_BLOCK, - VALA_STATEMENT_TYPE_EXPRESSION, - VALA_STATEMENT_TYPE_IF, - VALA_STATEMENT_TYPE_WHILE, - VALA_STATEMENT_TYPE_FOR, - VALA_STATEMENT_TYPE_FOREACH, - VALA_STATEMENT_TYPE_RETURN, - VALA_STATEMENT_TYPE_VARIABLE_DECLARATION, -}; - -enum _ValaExpressionType { - VALA_EXPRESSION_TYPE_ASSIGNMENT, - VALA_EXPRESSION_TYPE_CAST, - VALA_EXPRESSION_TYPE_ELEMENT_ACCESS, - VALA_EXPRESSION_TYPE_EXPRESSION, - VALA_EXPRESSION_TYPE_INVOCATION, - VALA_EXPRESSION_TYPE_IS, - VALA_EXPRESSION_TYPE_LITERAL_BOOLEAN, - VALA_EXPRESSION_TYPE_LITERAL_CHARACTER, - VALA_EXPRESSION_TYPE_LITERAL_INTEGER, - VALA_EXPRESSION_TYPE_LITERAL_NULL, - VALA_EXPRESSION_TYPE_LITERAL_STRING, - VALA_EXPRESSION_TYPE_MEMBER_ACCESS, - VALA_EXPRESSION_TYPE_OBJECT_CREATION, - VALA_EXPRESSION_TYPE_OPERATION, - VALA_EXPRESSION_TYPE_PARENTHESIZED, - VALA_EXPRESSION_TYPE_POSTFIX, - VALA_EXPRESSION_TYPE_RETURN, - VALA_EXPRESSION_TYPE_SIMPLE_NAME, - VALA_EXPRESSION_TYPE_STRUCT_OR_ARRAY_INITIALIZER, - VALA_EXPRESSION_TYPE_THIS_ACCESS, -}; - -enum _ValaOpType { - VALA_OP_TYPE_PLUS, - VALA_OP_TYPE_MINUS, - VALA_OP_TYPE_MUL, - VALA_OP_TYPE_DIV, - VALA_OP_TYPE_EQ, - VALA_OP_TYPE_NE, - VALA_OP_TYPE_LT, - VALA_OP_TYPE_GT, - VALA_OP_TYPE_LE, - VALA_OP_TYPE_GE, - VALA_OP_TYPE_NEG, - VALA_OP_TYPE_AND, - VALA_OP_TYPE_BITWISE_AND, - VALA_OP_TYPE_OR, - VALA_OP_TYPE_BITWISE_OR, -}; - -struct _ValaContext { - GList *source_files; - GList *imported_namespaces; - ValaSymbol *root; -}; - -struct _ValaSymbol { - ValaSymbolType type; - union { - ValaClass *class; - ValaStruct *struct_; - ValaEnum *enum_; - ValaConstant *constant; - ValaMethod *method; - ValaStatement *stmt; - ValaTypeReference *typeref; - ValaField *field; - ValaProperty *property; - ValaEnumValue *enum_value; - }; - GHashTable *symbol_table; -}; - -struct _ValaSourceFile { - const char *filename; - ValaNamespace *root_namespace; - GList *namespaces; - GList *using_directives; - GList *dep_types; -}; - -struct _ValaLocation { - ValaSourceFile *source_file; - int lineno; - int colno; -}; - -struct _ValaNamespace { - char *name; - ValaSymbol *symbol; - ValaSourceFile *source_file; - GList *classes; - GList *structs; - GList *enums; - GList *flags_list; - GList *methods; - GList *fields; - char *cprefix; - char *lower_case_cname; - char *upper_case_cname; - char *include_filename; - GList *annotations; - gboolean import; -}; - -struct _ValaClass { - char *name; - ValaLocation *location; - ValaSymbol *symbol; - ValaNamespace *namespace; - ValaClass *base_class; - GList *base_types; - GList *methods; - GList *fields; - GList *constants; - GList *properties; - GList *type_parameters; - char *cname; - char *lower_case_cname; - char *upper_case_cname; - ValaMethod *init_method; - ValaMethod *class_init_method; - GList *annotations; - gboolean has_private_fields; -}; - -struct _ValaStruct { - char *name; - ValaLocation *location; - ValaSymbol *symbol; - ValaNamespace *namespace; - gboolean reference_type; - GList *methods; - GList *fields; - GList *type_parameters; - char *cname; - char *lower_case_cname; - char *upper_case_cname; - GList *annotations; -}; - -struct _ValaEnum { - char *name; - ValaLocation *location; - ValaSymbol *symbol; - ValaNamespace *namespace; - GList *values; - char *cname; - char *upper_case_cname; - GList *annotations; -}; - -struct _ValaFlags { - char *name; - ValaLocation *location; - ValaSymbol *symbol; - ValaNamespace *namespace; - GList *values; - char *cname; - char *upper_case_cname; - GList *annotations; -}; - -struct _ValaMethod { - char *name; - ValaLocation *location; - ValaSymbol *symbol; - gboolean is_struct_method; - union { - ValaClass *class; - ValaStruct *struct_; - }; - ValaNamespace *namespace; /* only defined for methods outside a class */ - ValaTypeReference *return_type; - GList *formal_parameters; - ValaModifierFlags modifiers; - char *cname; - char *cdecl1; - char *cparameters; - ValaStatement *body; - gboolean returns_modified_pointer; - gboolean instance_last; - GList *annotations; - ValaClass *virtual_super_class; -}; - -struct _ValaField { - ValaLocation *location; - ValaSymbol *symbol; - gboolean is_struct_field; - union { - ValaClass *class; - ValaStruct *struct_; - }; - ValaNamespace *namespace; /* only defined for methods outside a class */ - ValaModifierFlags modifiers; - char *cname; - ValaStatement *declaration_statement; - GList *annotations; -}; - -struct _ValaConstant { - ValaLocation *location; - ValaSymbol *symbol; - ValaClass *class; - ValaModifierFlags modifiers; - ValaStatement *declaration_statement; -}; - -struct _ValaProperty { - char *name; - ValaLocation *location; - ValaSymbol *symbol; - ValaClass *class; - ValaTypeReference *return_type; - ValaModifierFlags modifiers; - ValaStatement *get_statement; - ValaStatement *set_statement; -}; - -struct _ValaEnumValue { - char *name; - char *value; - ValaSymbol *symbol; - char *cname; -}; - -struct _ValaFlagsValue { - char *name; - char *value; - ValaSymbol *symbol; - char *cname; -}; - -struct _ValaStatement { - ValaStatementType type; - ValaLocation *location; - union { - ValaSymbol *method; - }; - union { - struct { - GList *statements; - } block; - ValaExpression *expr; - ValaVariableDeclaration *variable_declaration; - struct { - ValaExpression *condition; - ValaStatement *true_stmt; - ValaStatement *false_stmt; - } if_stmt; - struct { - ValaExpression *condition; - ValaStatement *loop; - } while_stmt; - struct { - GList *initializer; - ValaExpression *condition; - GList *iterator; - ValaStatement *loop; - } for_stmt; - struct { - ValaTypeReference *type; - char *name; - ValaExpression *container; - ValaStatement *loop; - } foreach_stmt; - }; -}; - -struct _ValaVariableDeclaration { - ValaTypeReference *type; - ValaVariableDeclarator *declarator; -}; - -struct _ValaVariableDeclarator { - char *name; - ValaLocation *location; - ValaExpression *initializer; -}; - -struct _ValaExpression { - ValaExpressionType type; - ValaLocation *location; - ValaSymbol *static_type_symbol; - ValaSymbol *static_symbol; - ValaField *field; - ValaProperty *property; - gboolean array_type; - gboolean ref_variable; - gboolean out_variable; - union { - char *str; - int num; - GList *list; - ValaExpression *inner; - struct { - ValaExpression *left; - ValaOpType type; - ValaExpression *right; - } op; - struct { - ValaExpression *inner; - ValaTypeReference *type; - } cast; - struct { - ValaExpression *left; - char *right; - } member_access; - struct { - ValaExpression *call; - GList *argument_list; - ValaExpression *instance; - } invocation; - struct { - ValaExpression *left; - ValaExpression *right; - } assignment; - struct { - ValaTypeReference *type; - GList *named_argument_list; - } object_creation; - struct { - ValaExpression *inner; - const char *cop; - } postfix; - struct { - ValaExpression *array; - ValaExpression *index; - } element_access; - struct { - ValaExpression *expr; - ValaTypeReference *type; - } is; - }; -}; - -struct _ValaTypeReference { - char *namespace_name; - char *type_name; - ValaLocation *location; - ValaSymbol *symbol; - gboolean own; - gboolean array_type; - int type_param_index; /* for type references within generic types */ - GList *type_params; /* for type references referring to generic types */ -}; - -struct _ValaFormalParameter { - char *name; - ValaTypeReference *type; - ValaLocation *location; - ValaFormalParameterFlags modifier; -}; - -struct _ValaNamedArgument { - char *name; - ValaExpression *expression; - ValaLocation *location; - ValaSymbol *symbol; /* symbol corresponding to name */ -}; - -struct _ValaAnnotation { - ValaTypeReference *type; - GList *argument_list; -}; - -ValaContext *vala_context_new (); -void vala_context_free (ValaContext *context); -void vala_context_parse (ValaContext *context); -void vala_context_add_fundamental_symbols (ValaContext *context); -void vala_context_add_symbols_from_source_files (ValaContext *context); -void vala_context_resolve_types (ValaContext *context); - -ValaSourceFile *vala_source_file_new (const char *filename); - -void vala_parser_parse (ValaSourceFile *source_file); - -ValaSymbol *vala_symbol_new (ValaSymbolType type); - -void err (ValaLocation *location, const char *format, ...); diff --git a/vala/valac/driver.c b/vala/valac/driver.c deleted file mode 100644 index 84dc3d6..0000000 --- a/vala/valac/driver.c +++ /dev/null @@ -1,116 +0,0 @@ -/* driver.c - * - * Copyright (C) 2006 Jürg Billeter - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: - * Jürg Billeter - */ - -#include - -#include "context.h" -#include "generator.h" - -static int -driver_main (char **sources, char *directory) -{ - /* - * Parse source files - * Load metadata from specified gidl files into symbol tables - * Copy namespace and type names from parse tree into symbol tables - * Resolve type references in parse tree - * Load metadata from parse tree into symbol tables - * Add memory management calls - * Generate code - */ - - ValaContext *context = vala_context_new (); - - char **file; - for (file = sources; *file != NULL; file++) { - context->source_files = g_list_prepend (context->source_files, vala_source_file_new (g_strdup (*file))); - } - context->source_files = g_list_reverse (context->source_files); - g_strfreev (sources); - sources = NULL; - - vala_context_parse (context); - vala_context_add_fundamental_symbols (context); - vala_context_add_symbols_from_source_files (context); - vala_context_add_alias (context); - vala_context_resolve_types (context); - - ValaCodeGenerator *generator = vala_code_generator_new (context); - generator->directory = directory; - vala_code_generator_run (generator); - vala_code_generator_free (generator); - - vala_context_free (context); - context = NULL; - - return 0; -} - -int -main (int argc, char **argv) -{ - GError *error = NULL; - GOptionContext *option_context; - - char *directory = NULL; - gboolean version = FALSE; - char **sources = NULL; - - const GOptionEntry options[] = { - { "directory", 'd', 0, G_OPTION_ARG_FILENAME, &directory, "Output directory", "DIRECTORY" }, - { "version", 0, 0, G_OPTION_ARG_NONE, &version, "Display version number", NULL }, - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &sources, NULL, "FILE..." }, - { NULL } - }; - - option_context = g_option_context_new ("- Vala Compiler"); - g_option_context_set_help_enabled (option_context, TRUE); - g_option_context_add_main_entries (option_context, options, NULL); - g_option_context_parse (option_context, &argc, &argv, &error); - - if (error != NULL) { - return 1; - } - - if (version) { - return 0; - } - - if (*sources == NULL) { - printf ("No source file specified.\n"); - return 1; - } - - char **f; - for (f = sources; *f != NULL; f++) { - if (!g_str_has_suffix (*f, ".vala")) { - printf ("Only .vala source files supported.\n"); - return 1; - } - } - - directory = g_strdup (directory); - sources = g_strdupv (sources); - g_option_context_free (option_context); - - return driver_main (sources, directory); -} diff --git a/vala/valac/generator.c b/vala/valac/generator.c deleted file mode 100644 index 000c2b6..0000000 --- a/vala/valac/generator.c +++ /dev/null @@ -1,1889 +0,0 @@ -/* generator.c - * - * Copyright (C) 2006 Jürg Billeter, Raffaele Sandrini - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: - * Jürg Billeter - * Raffaele Sandrini - */ - -#include -#include -#include - -#include - -#include "context.h" -#include "generator.h" - -ValaCodeGenerator * -vala_code_generator_new (ValaContext *context) -{ - ValaCodeGenerator *generator = g_new0 (ValaCodeGenerator, 1); - - generator->context = context; - - return generator; -} - -static char * -filename_to_define (const char *filename) -{ - char *define = g_path_get_basename (filename); - char *p; - for (p = define; *p != '\0'; p++) { - if (g_ascii_isalnum (*p)) { - *p = toupper (*p); - } else { - *p = '_'; - } - } - - return define; -} - -static char * -get_cname_for_type_reference (ValaTypeReference *type, gboolean constant, ValaLocation *location) -{ - switch (type->symbol->type) { - case VALA_SYMBOL_TYPE_CLASS: - return g_strdup_printf ("%s *%s", type->symbol->class->cname, type->array_type ? "*" : ""); - case VALA_SYMBOL_TYPE_STRUCT: - if (constant && type->array_type) { - return g_strdup_printf ("const %s %s", type->symbol->struct_->cname, (type->symbol->struct_->reference_type ? "*" : "")); - } - return g_strdup_printf ("%s%s %s%s", constant ? "const " : "", type->symbol->struct_->cname, (type->symbol->struct_->reference_type ? "*" : ""), type->array_type ? "*" : ""); - case VALA_SYMBOL_TYPE_ENUM: - return g_strdup_printf ("%s ", type->symbol->enum_->cname); - case VALA_SYMBOL_TYPE_VOID: - return g_strdup ("void"); - default: - err (location, "internal error: unhandled symbol type %d", type->symbol->type); - return NULL; - } -} - -static char * -get_cname_for_static_expression_type (ValaExpression *expr, ValaLocation *location) -{ - switch (expr->static_type_symbol->type) { - case VALA_SYMBOL_TYPE_CLASS: - return g_strdup_printf ("%s *%s", expr->static_type_symbol->class->cname, expr->array_type ? "*" : ""); - case VALA_SYMBOL_TYPE_STRUCT: - return g_strdup_printf ("%s %s%s", expr->static_type_symbol->struct_->cname, (expr->static_type_symbol->struct_->reference_type ? "*" : ""), expr->array_type ? "*" : ""); - case VALA_SYMBOL_TYPE_VOID: - return g_strdup ("void"); - default: - err (location, "internal error: unhandled symbol type %d", expr->static_type_symbol->type); - return NULL; - } -} - -static void -vala_code_generator_process_methods1 (ValaCodeGenerator *generator, ValaClass *class) -{ - GList *l; - - char *camel_case; - char *ns_lower; - char *ns_upper; - - ValaNamespace *namespace = class->namespace; - - ns_lower = namespace->lower_case_cname; - ns_upper = namespace->upper_case_cname; - - char *lower_case = class->lower_case_cname; - char *upper_case = class->upper_case_cname; - - for (l = class->methods; l != NULL; l = l->next) { - ValaMethod *method = l->data; - - char *method_return_type_cname = get_cname_for_type_reference (method->return_type, FALSE, method->location); - if (method->cname == NULL) { - method->cname = g_strdup_printf ("%s%s_%s", ns_lower, lower_case, method->name); - } - - if (namespace->import) - continue; - - char *parameters; - GList *parameter_list = NULL; - if ((method->modifiers & VALA_MODIFIER_STATIC) == 0) { - if (method->modifiers & VALA_MODIFIER_OVERRIDE) { - ValaClass *super_class = class->base_class; - while (super_class != NULL) { - GList *vml; - for (vml = super_class->methods; vml != NULL; vml = vml->next) { - ValaMethod *vmethod = vml->data; - if (strcmp (vmethod->name, method->name) == 0 && (vmethod->modifiers & (VALA_MODIFIER_ABSTRACT | VALA_MODIFIER_VIRTUAL))) { - break; - } - } - if (vml != NULL) { - break; - } - super_class = super_class->base_class; - } - if (super_class == NULL) { - err (method->location, "error: no overridable method ´%s´ found", method->name); - } - method->virtual_super_class = super_class; - parameter_list = g_list_append (parameter_list, g_strdup_printf ("%s *base", method->virtual_super_class->cname)); - } else { - parameter_list = g_list_append (parameter_list, g_strdup_printf ("%s *self", class->cname)); - } - } - - GList *pl; - for (pl = method->formal_parameters; pl != NULL; pl = pl->next) { - ValaFormalParameter *param = pl->data; - char *param_string = g_strdup_printf ("%s%s", get_cname_for_type_reference (param->type, FALSE, param->location), param->name); - parameter_list = g_list_append (parameter_list, param_string); - } - - if (parameter_list == NULL) { - method->cparameters = g_strdup (""); - } else { - method->cparameters = parameter_list->data; - GList *sl; - for (sl = parameter_list->next; sl != NULL; sl = sl->next) { - method->cparameters = g_strdup_printf ("%s, %s", method->cparameters, sl->data); - g_free (sl->data); - } - g_list_free (parameter_list); - } - - if (method->modifiers & VALA_MODIFIER_PUBLIC) { - method->cdecl1 = g_strdup (method_return_type_cname); - } else { - method->cdecl1 = g_strdup_printf ("static %s", method_return_type_cname); - fprintf (generator->c_file, "%s %s (%s);\n", method->cdecl1, method->cname, method->cparameters); - } - - if (strcmp (method->name, "init") == 0) { - if (method->modifiers & VALA_MODIFIER_STATIC) { - err (method->location, "error: instance initializer must not be static"); - } - if (method->formal_parameters != NULL) { - err (method->location, "error: instance initializer must not have any arguments"); - } - class->init_method = method; - } else if (strcmp (method->name, "class_init") == 0) { - if ((method->modifiers & VALA_MODIFIER_STATIC) == 0) { - err (method->location, "error: class initializer must be static"); - } - if (method->formal_parameters != NULL) { - err (method->location, "error: class initializer must not have any arguments"); - } - class->class_init_method = method; - } - } - fprintf (generator->c_file, "\n"); -} - -static void -vala_code_generator_process_ns_method (ValaCodeGenerator *generator, ValaNamespace *namespace, ValaMethod *method) -{ - if (method->cname == NULL) { - method->cname = g_strdup_printf ("%s%s", namespace->lower_case_cname, method->name); - } -} - -static void -vala_code_generator_process_struct_methods1 (ValaCodeGenerator *generator, ValaStruct *struct_) -{ - GList *l; - - char *camel_case; - char *ns_lower; - char *ns_upper; - - ValaNamespace *namespace = struct_->namespace; - - ns_lower = namespace->lower_case_cname; - ns_upper = namespace->upper_case_cname; - - char *lower_case = struct_->lower_case_cname; - char *upper_case = struct_->upper_case_cname; - - for (l = struct_->methods; l != NULL; l = l->next) { - ValaMethod *method = l->data; - - char *method_return_type_cname = get_cname_for_type_reference (method->return_type, FALSE, method->location); - if (method->cname == NULL) { - method->cname = g_strdup_printf ("%s%s_%s", ns_lower, lower_case, method->name); - } - - char *parameters; - GList *parameter_list = NULL; - if ((method->modifiers & VALA_MODIFIER_STATIC) == 0) { - parameter_list = g_list_append (parameter_list, g_strdup_printf ("%s *self", struct_->cname)); - } - - GList *pl; - for (pl = method->formal_parameters; pl != NULL; pl = pl->next) { - ValaFormalParameter *param = pl->data; - char *param_string = g_strdup_printf ("%s%s", get_cname_for_type_reference (param->type, FALSE, param->location), param->name); - parameter_list = g_list_append (parameter_list, param_string); - } - - if (parameter_list == NULL) { - method->cparameters = g_strdup (""); - } else { - method->cparameters = parameter_list->data; - GList *sl; - for (sl = parameter_list->next; sl != NULL; sl = sl->next) { - method->cparameters = g_strdup_printf ("%s, %s", method->cparameters, sl->data); - g_free (sl->data); - } - g_list_free (parameter_list); - } - - if (method->modifiers & VALA_MODIFIER_PUBLIC) { - method->cdecl1 = g_strdup (method_return_type_cname); - } else { - method->cdecl1 = g_strdup_printf ("static %s", method_return_type_cname); - fprintf (generator->c_file, "%s %s (%s);\n", method->cdecl1, method->cname, method->cparameters); - } - } - fprintf (generator->c_file, "\n"); -} - -static void vala_code_generator_process_expression (ValaCodeGenerator *generator, ValaExpression *expr); - -static void -vala_code_generator_process_operation_expression (ValaCodeGenerator *generator, ValaExpression *expr) -{ - char *cop = ""; - if (expr->op.left != NULL) { - vala_code_generator_process_expression (generator, expr->op.left); - } - switch (expr->op.type) { - case VALA_OP_TYPE_PLUS: - cop = "+"; - break; - case VALA_OP_TYPE_MINUS: - cop = "-"; - break; - case VALA_OP_TYPE_MUL: - cop = "*"; - break; - case VALA_OP_TYPE_DIV: - cop = "/"; - break; - case VALA_OP_TYPE_EQ: - cop = "=="; - break; - case VALA_OP_TYPE_NE: - cop = "!="; - break; - case VALA_OP_TYPE_LT: - cop = "<"; - break; - case VALA_OP_TYPE_GT: - cop = ">"; - break; - case VALA_OP_TYPE_LE: - cop = "<="; - break; - case VALA_OP_TYPE_GE: - cop = ">="; - break; - case VALA_OP_TYPE_NEG: - cop = "!"; - break; - case VALA_OP_TYPE_AND: - cop = "&&"; - break; - case VALA_OP_TYPE_BITWISE_AND: - cop = "&"; - break; - case VALA_OP_TYPE_OR: - cop = "||"; - break; - case VALA_OP_TYPE_BITWISE_OR: - cop = "|"; - break; - } - fprintf (generator->c_file, " %s ", cop); - vala_code_generator_process_expression (generator, expr->op.right); -} - -static ValaSymbol * -get_inherited_member (ValaSymbol *type, const char *name, ValaLocation *location, gboolean break_on_failure) -{ - ValaSymbol *sym; - sym = g_hash_table_lookup (type->symbol_table, name); - if (sym != NULL) { - if (sym->type == VALA_SYMBOL_TYPE_METHOD && (sym->method->modifiers & VALA_MODIFIER_OVERRIDE)) { - /* don't return overriden method - * return virtual method from corresponding super class */ - } else { - return sym; - } - } - - if (type->type != VALA_SYMBOL_TYPE_CLASS || type->class->base_class == NULL) { - if (break_on_failure) { - err (location, "error: type member ´%s´ not found", name); - } - - return NULL; - } - - return get_inherited_member (type->class->base_class->symbol, name, location, break_on_failure); -} - -static void -vala_code_generator_find_static_type_of_expression (ValaCodeGenerator *generator, ValaExpression *expr) -{ - ValaSymbol *sym = NULL, *sym2 = NULL; - - if (expr->static_type_symbol != NULL) - return; - - switch (expr->type) { - case VALA_EXPRESSION_TYPE_ASSIGNMENT: - break; - case VALA_EXPRESSION_TYPE_CAST: - expr->static_type_symbol = expr->cast.type->symbol; - break; - case VALA_EXPRESSION_TYPE_ELEMENT_ACCESS: - vala_code_generator_find_static_type_of_expression (generator, expr->element_access.array); - if (!expr->element_access.array->array_type) { - err (expr->element_access.index->location, "error: expression preceding indexer is not an array"); - } - expr->static_type_symbol = expr->element_access.array->static_type_symbol; - break; - case VALA_EXPRESSION_TYPE_INVOCATION: - vala_code_generator_find_static_type_of_expression (generator, expr->invocation.call); - expr->array_type = expr->invocation.call->static_type_symbol->method->return_type->array_type; - expr->static_type_symbol = expr->invocation.call->static_type_symbol->method->return_type->symbol; - break; - case VALA_EXPRESSION_TYPE_IS: - expr->static_type_symbol = g_hash_table_lookup (generator->context->root->symbol_table, "bool"); - break; - case VALA_EXPRESSION_TYPE_MEMBER_ACCESS: - vala_code_generator_find_static_type_of_expression (generator, expr->member_access.left); - sym = expr->member_access.left->static_type_symbol; - if (sym != NULL && sym->type == VALA_SYMBOL_TYPE_CLASS) { - expr->static_type_symbol = get_inherited_member (sym, expr->member_access.right, expr->member_access.left->location, TRUE); - if (expr->static_type_symbol->type == VALA_SYMBOL_TYPE_FIELD) { - expr->field = expr->static_type_symbol->field; - expr->array_type = expr->static_type_symbol->field->declaration_statement->variable_declaration->type->array_type; - expr->static_type_symbol = expr->static_type_symbol->field->declaration_statement->variable_declaration->type->symbol; - } else if (expr->static_type_symbol->type == VALA_SYMBOL_TYPE_PROPERTY) { - expr->property = expr->static_type_symbol->property; - expr->array_type = expr->static_type_symbol->property->return_type->array_type; - expr->static_type_symbol = expr->static_type_symbol->property->return_type->symbol; - } - } else if (sym != NULL && sym->type == VALA_SYMBOL_TYPE_STRUCT) { - expr->static_type_symbol = g_hash_table_lookup (sym->symbol_table, expr->member_access.right); - if (expr->static_type_symbol == NULL) { - err (expr->member_access.left->location, "error: struct member ´%s´ not found", expr->member_access.right); - } - if (expr->static_type_symbol->type == VALA_SYMBOL_TYPE_FIELD) { - expr->field = expr->static_type_symbol->field; - expr->array_type = expr->static_type_symbol->field->declaration_statement->variable_declaration->type->array_type; - expr->static_type_symbol = expr->static_type_symbol->field->declaration_statement->variable_declaration->type->symbol; - } - } else if (sym != NULL && sym->type == VALA_SYMBOL_TYPE_ENUM) { - expr->static_symbol = g_hash_table_lookup (sym->symbol_table, expr->member_access.right); - if (expr->static_symbol == NULL) { - err (expr->member_access.left->location, "error: enum member ´%s´ not found", expr->member_access.right); - } - - expr->static_type_symbol = g_hash_table_lookup (generator->context->root->symbol_table, "int"); - } else if (sym != NULL && sym->type == VALA_SYMBOL_TYPE_NAMESPACE) { - expr->static_type_symbol = g_hash_table_lookup (sym->symbol_table, expr->member_access.right); - if (expr->static_type_symbol == NULL) { - err (expr->member_access.left->location, "error: namespace member ´%s´ not found", expr->member_access.right); - } - } else { - err (expr->member_access.left->location, "error: specified symbol type %d can't be used for member access", sym->type); - } - break; - case VALA_EXPRESSION_TYPE_OBJECT_CREATION: - expr->static_type_symbol = expr->object_creation.type->symbol; - break; - case VALA_EXPRESSION_TYPE_OPERATION: - switch (expr->op.type) { - case VALA_OP_TYPE_PLUS: - case VALA_OP_TYPE_MINUS: - if (expr->op.left != NULL) { - /* required for pointer arithmetic */ - vala_code_generator_find_static_type_of_expression (generator, expr->op.left); - expr->static_type_symbol = expr->op.left->static_type_symbol; - } - break; - } - break; - case VALA_EXPRESSION_TYPE_PARENTHESIZED: - vala_code_generator_find_static_type_of_expression (generator, expr->inner); - expr->static_type_symbol = expr->inner->static_type_symbol; - break; - case VALA_EXPRESSION_TYPE_LITERAL_INTEGER: - break; - case VALA_EXPRESSION_TYPE_LITERAL_STRING: - expr->static_type_symbol = g_hash_table_lookup (generator->context->root->symbol_table, "string"); - break; - case VALA_EXPRESSION_TYPE_SIMPLE_NAME: - if (expr->static_type_symbol == NULL) { - /* local variable */ - if (generator->sym != NULL) { - sym = g_hash_table_lookup (generator->sym->symbol_table, expr->str); - - if (sym != NULL) { - expr->static_type_symbol = sym->typeref->symbol; - expr->array_type = sym->typeref->array_type; - } - } - } - - if (expr->static_type_symbol == NULL) { - /* member of this */ - expr->static_type_symbol = get_inherited_member (generator->class->symbol, expr->str, expr->location, FALSE); - } - - if (expr->static_type_symbol == NULL) { - /* member of the current namespace */ - expr->static_type_symbol = g_hash_table_lookup (generator->class->namespace->symbol->symbol_table, expr->str); - } - - if (expr->static_type_symbol == NULL) { - /* member of the root namespace */ - expr->static_type_symbol = g_hash_table_lookup (generator->context->root->symbol_table, expr->str); - } - - if (expr->static_type_symbol == NULL) { - /* member of a namespace specified by a using directive */ - - gboolean found = FALSE; - GList *l; - for (l = generator->class->namespace->source_file->using_directives; l != NULL; l = l->next) { - ValaSymbol *ns_symbol = g_hash_table_lookup (generator->context->root->symbol_table, l->data); - if (ns_symbol == NULL) { - err (expr->location, "error: namespace ´%s´ specified by using directive not found", l->data); - } - expr->static_type_symbol = g_hash_table_lookup (ns_symbol->symbol_table, expr->str); - if (expr->static_type_symbol != NULL) { - if (found) { - err (expr->location, "error: symbol ´%s´ ambiguous", expr->str); - } - found = TRUE; - } - } - } - - if (expr->static_type_symbol != NULL) { - if (expr->static_type_symbol->type == VALA_SYMBOL_TYPE_FIELD) { - expr->field = expr->static_type_symbol->field; - expr->array_type = expr->static_type_symbol->field->declaration_statement->variable_declaration->type->array_type; - expr->static_type_symbol = expr->static_type_symbol->field->declaration_statement->variable_declaration->type->symbol; - } else if (expr->static_type_symbol->type == VALA_SYMBOL_TYPE_PROPERTY) { - expr->property = expr->static_type_symbol->property; - expr->array_type = expr->static_type_symbol->property->return_type->array_type; - expr->static_type_symbol = expr->static_type_symbol->property->return_type->symbol; - } - } - - if (expr->static_type_symbol == NULL) { - err (expr->location, "error: symbol ´%s´ not found", expr->str); - } - break; - case VALA_EXPRESSION_TYPE_THIS_ACCESS: - expr->static_type_symbol = generator->sym->stmt->method->method->class->symbol; - break; - } -} - -static void -vala_code_generator_process_assignment (ValaCodeGenerator *generator, ValaExpression *expr) -{ - vala_code_generator_find_static_type_of_expression (generator, expr->assignment.left); - - if (expr->assignment.left->property != NULL) { - fprintf (generator->c_file, "g_object_set ("); - switch (expr->assignment.left->type) { - case VALA_EXPRESSION_TYPE_SIMPLE_NAME: - fprintf (generator->c_file, "self"); - break; - case VALA_EXPRESSION_TYPE_MEMBER_ACCESS: - vala_code_generator_process_expression (generator, expr->assignment.left->member_access.left); - break; - default: - break; - } - fprintf (generator->c_file, ", \"%s\", ", expr->assignment.left->property->name); - - vala_code_generator_process_expression (generator, expr->assignment.right); - fprintf (generator->c_file, ", NULL);"); - return; - } - - vala_code_generator_process_expression (generator, expr->assignment.left); - fprintf (generator->c_file, " = "); - vala_code_generator_process_expression (generator, expr->assignment.right); -} - -static void -vala_code_generator_process_invocation (ValaCodeGenerator *generator, ValaExpression *expr) -{ - GList *l; - ValaMethod *method = NULL; - gboolean first = TRUE; - - vala_code_generator_find_static_type_of_expression (generator, expr->invocation.call); - method = expr->invocation.call->static_type_symbol->method; - switch (expr->invocation.call->type) { - case VALA_EXPRESSION_TYPE_MEMBER_ACCESS: - expr->invocation.instance = expr->invocation.call->member_access.left; - break; - } - - if (method->returns_modified_pointer) { - if (expr->static_type_symbol->type != VALA_SYMBOL_TYPE_VOID) { - err (method->location, "error: ReturnsModifiedPointer declared on a method with non-void return type"); - } - - if (expr->invocation.instance != NULL) { - vala_code_generator_process_expression (generator, expr->invocation.instance); - } else { - fprintf (generator->c_file, "self"); - } - fprintf (generator->c_file, " = "); - } - - vala_code_generator_process_expression (generator, expr->invocation.call); - fprintf (generator->c_file, " ("); - if (!method->instance_last && (method->modifiers & VALA_MODIFIER_STATIC) == 0) { - if (expr->invocation.instance != NULL) { - if (!method->is_struct_method && expr->invocation.instance->static_type_symbol != method->class->symbol) { - fprintf (generator->c_file, "%s%s(", method->class->namespace->upper_case_cname, method->class->upper_case_cname); - } - vala_code_generator_process_expression (generator, expr->invocation.instance); - if (!method->is_struct_method && expr->invocation.instance->static_type_symbol != method->class->symbol) { - fprintf (generator->c_file, ")"); - } - } else { - if (!method->is_struct_method && generator->class->symbol != method->class->symbol) { - fprintf (generator->c_file, "%s%s(", method->class->namespace->upper_case_cname, method->class->upper_case_cname); - } - fprintf (generator->c_file, "self"); - if (!method->is_struct_method && generator->class->symbol != method->class->symbol) { - fprintf (generator->c_file, ")"); - } - } - first = FALSE; - } - for (l = expr->invocation.argument_list; l != NULL; l = l->next) { - if (!first) { - fprintf (generator->c_file, ", "); - } else { - first = FALSE; - } - vala_code_generator_process_expression (generator, l->data); - } - if (method->instance_last && (method->modifiers & VALA_MODIFIER_STATIC) == 0) { - if (!first) { - fprintf (generator->c_file, ", "); - } - if (expr->invocation.instance != NULL) { - vala_code_generator_process_expression (generator, expr->invocation.instance); - } else { - fprintf (generator->c_file, "self"); - } - } - fprintf (generator->c_file, ")"); -} - -static void -vala_code_generator_process_literal (ValaCodeGenerator *generator, ValaExpression *expr) -{ - switch (expr->type) { - case VALA_EXPRESSION_TYPE_LITERAL_BOOLEAN: - fprintf (generator->c_file, "%s", expr->num ? "TRUE" : "FALSE"); - break; - case VALA_EXPRESSION_TYPE_LITERAL_NULL: - fprintf (generator->c_file, "NULL"); - break; - default: - fprintf (generator->c_file, "%s", expr->str); - break; - } -} - -static void -vala_code_generator_process_cast (ValaCodeGenerator *generator, ValaExpression *expr) -{ - if (expr->cast.type->symbol->type == VALA_SYMBOL_TYPE_CLASS) { - ValaClass *cl = expr->cast.type->symbol->class; - fprintf (generator->c_file, "%s%s (", cl->namespace->upper_case_cname, cl->upper_case_cname); - vala_code_generator_process_expression (generator, expr->cast.inner); - fprintf (generator->c_file, ")"); - } else { - fprintf (generator->c_file, "(%s) ", get_cname_for_type_reference (expr->cast.type, FALSE, expr->location)); - vala_code_generator_process_expression (generator, expr->cast.inner); - } -} - -static void -vala_code_generator_process_is (ValaCodeGenerator *generator, ValaExpression *expr) -{ - if (expr->is.type->symbol->type == VALA_SYMBOL_TYPE_CLASS) { - ValaClass *cl = expr->is.type->symbol->class; - fprintf (generator->c_file, "%sIS_%s (", cl->namespace->upper_case_cname, cl->upper_case_cname); - vala_code_generator_process_expression (generator, expr->is.expr); - fprintf (generator->c_file, ")"); - } else { - err (expr->location, "error: type check on non-class"); - } -} - -static void -vala_code_generator_process_element_access (ValaCodeGenerator *generator, ValaExpression *expr) -{ - vala_code_generator_process_expression (generator, expr->element_access.array); - fprintf (generator->c_file, "["); - vala_code_generator_process_expression (generator, expr->element_access.index); - fprintf (generator->c_file, "]"); -} - -static void -vala_code_generator_process_member_access (ValaCodeGenerator *generator, ValaExpression *expr) -{ - ValaSymbol *sym = expr->static_type_symbol; - if (sym->type == VALA_SYMBOL_TYPE_METHOD) { - ValaMethod *method = sym->method; - fprintf (generator->c_file, "%s", method->cname); - } else if (expr->static_symbol != NULL && expr->static_symbol->type == VALA_SYMBOL_TYPE_ENUM_VALUE) { - fprintf (generator->c_file, "%s", expr->static_symbol->enum_value->cname); - } else if (expr->property != NULL) { - fprintf (generator->c_file, "%s%s_get_%s (", expr->property->class->namespace->lower_case_cname, expr->property->class->lower_case_cname, expr->property->name); - vala_code_generator_process_expression (generator, expr->member_access.left); - fprintf (generator->c_file, ")"); - } else { - if (expr->field != NULL && !expr->field->is_struct_field) { - fprintf (generator->c_file, "%s%s(", expr->field->class->namespace->upper_case_cname, expr->field->class->upper_case_cname); - } - vala_code_generator_process_expression (generator, expr->member_access.left); - if (expr->field != NULL) { - if (!expr->field->is_struct_field) { - fprintf (generator->c_file, ")"); - } - - if ((expr->field->modifiers & VALA_MODIFIER_PRIVATE) != 0) { - fprintf (generator->c_file, "->priv->%s", expr->member_access.right); - } else { - fprintf (generator->c_file, "->%s", expr->member_access.right); - } - } - } -} - -static void -vala_code_generator_process_object_creation_expression (ValaCodeGenerator *generator, ValaExpression *expr) -{ - GList *l; - - fprintf (generator->c_file, "g_object_new (%sTYPE_%s", expr->object_creation.type->symbol->class->namespace->upper_case_cname, expr->object_creation.type->symbol->class->upper_case_cname); - - for (l = expr->object_creation.named_argument_list; l != NULL; l = l->next) { - ValaNamedArgument *arg = l->data; - fprintf (generator->c_file, ", \"%s\", ", arg->name); - vala_code_generator_process_expression (generator, arg->expression); - } - - fprintf (generator->c_file, ", NULL)"); -} - -static void -vala_code_generator_process_parenthesized_expression (ValaCodeGenerator *generator, ValaExpression *expr) -{ - fprintf (generator->c_file, "("); - vala_code_generator_process_expression (generator, expr->inner); - fprintf (generator->c_file, ")"); -} - -static void -vala_code_generator_process_postfix_expression (ValaCodeGenerator *generator, ValaExpression *expr) -{ - vala_code_generator_process_expression (generator, expr->postfix.inner); - fprintf (generator->c_file, "%s", expr->postfix.cop); -} - -static void -vala_code_generator_process_simple_name (ValaCodeGenerator *generator, ValaExpression *expr) -{ - if (expr->ref_variable || expr->out_variable) { - fprintf (generator->c_file, "&"); - } - - if (expr->field != NULL) { - ValaField *field = expr->field; - - if (field->class != NULL) { - ValaClass *class = field->class; - char *ns_upper = class->namespace->upper_case_cname; - char *class_upper = class->upper_case_cname; - - if ((field->modifiers & (VALA_MODIFIER_STATIC | VALA_MODIFIER_PRIVATE)) == (VALA_MODIFIER_STATIC | VALA_MODIFIER_PRIVATE)) { - fprintf (generator->c_file, "%s", expr->str); - } else if ((field->modifiers & VALA_MODIFIER_STATIC) != 0) { - fprintf (generator->c_file, "%s%s_GET_CLASS(self)->%s", ns_upper, class_upper, expr->str); - } else if ((field->modifiers & VALA_MODIFIER_PRIVATE) != 0) { - fprintf (generator->c_file, "self->priv->%s", expr->str); - } else if ((field->modifiers & VALA_MODIFIER_PUBLIC) != 0) { - fprintf (generator->c_file, "%s%s(self)->%s", ns_upper, class_upper, expr->str); - } - - return; - } else if (field->namespace != NULL) { - ValaNamespace *ns = field->namespace; - - if (field->cname != NULL) { - fprintf (generator->c_file, "%s", field->cname); - } else { - fprintf (generator->c_file, "%s%s", ns->lower_case_cname, expr->str); - } - - return; - } - } else if (expr->property != NULL) { - fprintf (generator->c_file, "%s%s_get_%s (self)", expr->property->class->namespace->lower_case_cname, expr->property->class->lower_case_cname, expr->property->name); - return; - } - - switch (expr->static_type_symbol->type) { - case VALA_SYMBOL_TYPE_METHOD: - fprintf (generator->c_file, "%s", expr->static_type_symbol->method->cname); - break; - default: - fprintf (generator->c_file, "%s", expr->str); - break; - } -} - -static void -vala_code_generator_process_struct_or_array_initializer (ValaCodeGenerator *generator, ValaExpression *expr) -{ - GList *l; - gboolean first = TRUE; - - fprintf (generator->c_file, "{ "); - - for (l = expr->list; l != NULL; l = l->next) { - if (!first) { - fprintf (generator->c_file, ", "); - } else { - first = FALSE; - } - vala_code_generator_process_expression (generator, l->data); - } - - fprintf (generator->c_file, " }"); -} - -static void -vala_code_generator_process_this_access (ValaCodeGenerator *generator, ValaExpression *expr) -{ - fprintf (generator->c_file, "self"); -} - -static void -vala_code_generator_process_expression (ValaCodeGenerator *generator, ValaExpression *expr) -{ - vala_code_generator_find_static_type_of_expression (generator, expr); - - switch (expr->type) { - case VALA_EXPRESSION_TYPE_ASSIGNMENT: - vala_code_generator_process_assignment (generator, expr); - break; - case VALA_EXPRESSION_TYPE_CAST: - vala_code_generator_process_cast (generator, expr); - break; - case VALA_EXPRESSION_TYPE_ELEMENT_ACCESS: - vala_code_generator_process_element_access (generator, expr); - break; - case VALA_EXPRESSION_TYPE_INVOCATION: - vala_code_generator_process_invocation (generator, expr); - break; - case VALA_EXPRESSION_TYPE_IS: - vala_code_generator_process_is (generator, expr); - break; - case VALA_EXPRESSION_TYPE_MEMBER_ACCESS: - vala_code_generator_process_member_access (generator, expr); - break; - case VALA_EXPRESSION_TYPE_OBJECT_CREATION: - vala_code_generator_process_object_creation_expression (generator, expr); - break; - case VALA_EXPRESSION_TYPE_OPERATION: - vala_code_generator_process_operation_expression (generator, expr); - break; - case VALA_EXPRESSION_TYPE_PARENTHESIZED: - vala_code_generator_process_parenthesized_expression (generator, expr); - break; - case VALA_EXPRESSION_TYPE_POSTFIX: - vala_code_generator_process_postfix_expression (generator, expr); - break; - case VALA_EXPRESSION_TYPE_LITERAL_BOOLEAN: - case VALA_EXPRESSION_TYPE_LITERAL_CHARACTER: - case VALA_EXPRESSION_TYPE_LITERAL_INTEGER: - case VALA_EXPRESSION_TYPE_LITERAL_NULL: - case VALA_EXPRESSION_TYPE_LITERAL_STRING: - vala_code_generator_process_literal (generator, expr); - break; - case VALA_EXPRESSION_TYPE_SIMPLE_NAME: - vala_code_generator_process_simple_name (generator, expr); - break; - case VALA_EXPRESSION_TYPE_STRUCT_OR_ARRAY_INITIALIZER: - vala_code_generator_process_struct_or_array_initializer (generator, expr); - break; - case VALA_EXPRESSION_TYPE_THIS_ACCESS: - vala_code_generator_process_this_access (generator, expr); - break; - } -} - -static void -vala_code_generator_process_variable_declaration (ValaCodeGenerator *generator, ValaStatement *stmt) -{ - ValaTypeReference *type = stmt->variable_declaration->type; - ValaExpression *expr = stmt->variable_declaration->declarator->initializer; - if (type->type_name == NULL) { - /* var type: use type inference */ - g_assert (expr != NULL); - - vala_code_generator_find_static_type_of_expression (generator, expr); - type->symbol = expr->static_type_symbol; - } - - char *decl_string = get_cname_for_type_reference (type, FALSE, stmt->location); - - fprintf (generator->c_file, "\t%s%s", decl_string, stmt->variable_declaration->declarator->name); - - if (expr != NULL) { - fprintf (generator->c_file, " = "); - vala_code_generator_process_expression (generator, expr); - } - - fprintf (generator->c_file, ";\n"); - - ValaSymbol *sym = vala_symbol_new (VALA_SYMBOL_TYPE_LOCAL_VARIABLE); - g_hash_table_insert (generator->sym->symbol_table, stmt->variable_declaration->declarator->name, sym); - sym->typeref = stmt->variable_declaration->type; -} - -static void vala_code_generator_process_statement (ValaCodeGenerator *generator, ValaStatement *stmt); - -static void -vala_code_generator_process_block (ValaCodeGenerator *generator, ValaStatement *stmt) -{ - GList *l; - - fprintf (generator->c_file, "{\n"); - - for (l = stmt->block.statements; l != NULL; l = l->next) { - vala_code_generator_process_statement (generator, l->data); - } - - fprintf (generator->c_file, "}\n"); -} - -static void -vala_code_generator_process_statement_expression_list (ValaCodeGenerator *generator, GList *list) -{ - GList *l; - gboolean first = TRUE; - - for (l = list; l != NULL; l = l->next) { - if (!first) { - fprintf (generator->c_file, ", "); - } else { - first = FALSE; - } - vala_code_generator_process_expression (generator, l->data); - } -} - -static void -vala_code_generator_process_while_statement (ValaCodeGenerator *generator, ValaStatement *stmt) -{ - fprintf (generator->c_file, "\twhile ("); - vala_code_generator_process_expression (generator, stmt->while_stmt.condition); - fprintf (generator->c_file, ")\n"); - vala_code_generator_process_statement (generator, stmt->while_stmt.loop); -} - -static void -vala_code_generator_process_for_statement (ValaCodeGenerator *generator, ValaStatement *stmt) -{ - fprintf (generator->c_file, "\tfor ("); - vala_code_generator_process_statement_expression_list (generator, stmt->for_stmt.initializer); - fprintf (generator->c_file, "; "); - vala_code_generator_process_expression (generator, stmt->for_stmt.condition); - fprintf (generator->c_file, "; "); - vala_code_generator_process_statement_expression_list (generator, stmt->for_stmt.iterator); - fprintf (generator->c_file, ")\n"); - vala_code_generator_process_statement (generator, stmt->for_stmt.loop); -} - -static void -vala_code_generator_process_foreach_statement (ValaCodeGenerator *generator, ValaStatement *stmt) -{ - vala_code_generator_find_static_type_of_expression (generator, stmt->foreach_stmt.container); - - if (stmt->foreach_stmt.container->array_type) { - fprintf (generator->c_file, "\t%s%s_it;\n", get_cname_for_static_expression_type (stmt->foreach_stmt.container, stmt->location), stmt->foreach_stmt.name); - fprintf (generator->c_file, "\tfor ("); - fprintf (generator->c_file, "%s_it = ", stmt->foreach_stmt.name, stmt->foreach_stmt.name); - vala_code_generator_process_expression (generator, stmt->foreach_stmt.container); - fprintf (generator->c_file, "; "); - fprintf (generator->c_file, "*%s_it != NULL", stmt->foreach_stmt.name); - fprintf (generator->c_file, "; "); - fprintf (generator->c_file, "%s_it++", stmt->foreach_stmt.name); - fprintf (generator->c_file, ") {\n"); - fprintf (generator->c_file, "\t\t%s%s = *%s_it;\n", get_cname_for_type_reference (stmt->foreach_stmt.type, FALSE, stmt->location), stmt->foreach_stmt.name, stmt->foreach_stmt.name); - } else { - fprintf (generator->c_file, "\tGList *%s_it;\n", stmt->foreach_stmt.name); - fprintf (generator->c_file, "\tfor ("); - fprintf (generator->c_file, "%s_it = ", stmt->foreach_stmt.name); - vala_code_generator_process_expression (generator, stmt->foreach_stmt.container); - fprintf (generator->c_file, "; "); - fprintf (generator->c_file, "%s_it != NULL", stmt->foreach_stmt.name); - fprintf (generator->c_file, "; "); - fprintf (generator->c_file, "%s_it = %s_it->next", stmt->foreach_stmt.name, stmt->foreach_stmt.name); - fprintf (generator->c_file, ") {\n"); - fprintf (generator->c_file, "\t%s%s = %s_it->data;\n", get_cname_for_type_reference (stmt->foreach_stmt.type, FALSE, stmt->location), stmt->foreach_stmt.name, stmt->foreach_stmt.name); - } - - ValaSymbol *sym = vala_symbol_new (VALA_SYMBOL_TYPE_LOCAL_VARIABLE); - g_hash_table_insert (generator->sym->symbol_table, stmt->foreach_stmt.name, sym); - sym->typeref = stmt->foreach_stmt.type; - - vala_code_generator_process_statement (generator, stmt->foreach_stmt.loop); - - fprintf (generator->c_file, "}\n"); -} - -static void -vala_code_generator_process_if_statement (ValaCodeGenerator *generator, ValaStatement *stmt) -{ - GList *l; - - fprintf (generator->c_file, "\tif ("); - vala_code_generator_process_expression (generator, stmt->if_stmt.condition); - fprintf (generator->c_file, ")\n"); - vala_code_generator_process_statement (generator, stmt->if_stmt.true_stmt); - if (stmt->if_stmt.false_stmt != NULL) { - fprintf (generator->c_file, "\telse "); - vala_code_generator_process_statement (generator, stmt->if_stmt.false_stmt); - } -} - -static void -vala_code_generator_process_return_statement (ValaCodeGenerator *generator, ValaStatement *stmt) -{ - GList *l; - - fprintf (generator->c_file, "\treturn "); - if (stmt->expr != NULL) { - vala_code_generator_process_expression (generator, stmt->expr); - } - fprintf (generator->c_file, ";\n"); -} - -static void -vala_code_generator_process_statement (ValaCodeGenerator *generator, ValaStatement *stmt) -{ - switch (stmt->type) { - case VALA_STATEMENT_TYPE_BLOCK: - vala_code_generator_process_block (generator, stmt); - break; - case VALA_STATEMENT_TYPE_EXPRESSION: - fprintf (generator->c_file, "\t"); - vala_code_generator_process_expression (generator, stmt->expr); - fprintf (generator->c_file, ";\n"); - break; - case VALA_STATEMENT_TYPE_WHILE: - vala_code_generator_process_while_statement (generator, stmt); - break; - case VALA_STATEMENT_TYPE_FOR: - vala_code_generator_process_for_statement (generator, stmt); - break; - case VALA_STATEMENT_TYPE_FOREACH: - vala_code_generator_process_foreach_statement (generator, stmt); - break; - case VALA_STATEMENT_TYPE_IF: - vala_code_generator_process_if_statement (generator, stmt); - break; - case VALA_STATEMENT_TYPE_RETURN: - vala_code_generator_process_return_statement (generator, stmt); - break; - case VALA_STATEMENT_TYPE_VARIABLE_DECLARATION: - vala_code_generator_process_variable_declaration (generator, stmt); - break; - default: - fprintf (generator->c_file, "\t;\n"); - } -} - -static GList* -get_fields_by_flag (ValaClass *class, ValaModifierFlags flag) -{ - GList *l,*ret = NULL; - ValaField *field; - - for (l = class->fields; l != NULL; l = l->next) { - field = l->data; - if (field->modifiers == flag) - ret = g_list_prepend (ret, field); - } - - return g_list_reverse (ret); -} - -static void -vala_code_generator_process_constants (ValaCodeGenerator *generator, ValaClass *class) -{ - GList *l; - - char *camel_case; - char *ns_lower; - char *ns_upper; - - ValaNamespace *namespace = class->namespace; - - ns_lower = namespace->lower_case_cname; - ns_upper = namespace->upper_case_cname; - - char *lower_case = class->lower_case_cname; - char *upper_case = class->upper_case_cname; - - for (l = class->constants; l != NULL; l = l->next) { - ValaConstant *constant = l->data; - - ValaStatement* stmt = constant->declaration_statement; - ValaTypeReference *type = stmt->variable_declaration->type; - ValaExpression *expr = stmt->variable_declaration->declarator->initializer; - if (type->type_name == NULL) { - /* var type: use type inference */ - g_assert (expr != NULL); - - vala_code_generator_find_static_type_of_expression (generator, expr); - type->symbol = expr->static_type_symbol; - } - - char *decl_string = get_cname_for_type_reference (type, TRUE, stmt->location); - - fprintf (generator->c_file, "%s%s%s", decl_string, stmt->variable_declaration->declarator->name, type->array_type ? "[]" : ""); - - if (expr != NULL) { - fprintf (generator->c_file, " = "); - vala_code_generator_process_expression (generator, expr); - } - - fprintf (generator->c_file, ";\n"); - - fprintf (generator->c_file, "\n"); - } -} - -static void -vala_code_generator_process_methods2 (ValaCodeGenerator *generator, ValaClass *class) -{ - GList *l; - - char *camel_case; - char *ns_lower; - char *ns_upper; - - ValaNamespace *namespace = class->namespace; - - ns_lower = namespace->lower_case_cname; - ns_upper = namespace->upper_case_cname; - - char *lower_case = class->lower_case_cname; - char *upper_case = class->upper_case_cname; - - for (l = class->methods; l != NULL; l = l->next) { - ValaMethod *method = l->data; - - if (strcmp (method->name, "init") == 0 || strcmp (method->name, "class_init") == 0) { - continue; - } - - if ((method->modifiers & VALA_MODIFIER_PUBLIC) && (method->modifiers & VALA_MODIFIER_OVERRIDE) == 0) { - fprintf (generator->h_file, "%s %s (%s);\n", method->cdecl1, method->cname, method->cparameters); - } - - if ((method->modifiers & VALA_MODIFIER_ABSTRACT) == 0 && method->body != NULL) { - if ((method->modifiers & (VALA_MODIFIER_VIRTUAL | VALA_MODIFIER_OVERRIDE)) == 0) { - fprintf (generator->c_file, "%s\n", method->cdecl1); - fprintf (generator->c_file, "%s (%s)\n", method->cname, method->cparameters); - } else { - fprintf (generator->c_file, "static %s\n", method->cdecl1); - fprintf (generator->c_file, "%s%s_real_%s (%s)\n", ns_lower, lower_case, method->name, method->cparameters); - } - - if (method->modifiers & VALA_MODIFIER_OVERRIDE) { - fprintf (generator->c_file, "{\n"); - fprintf (generator->c_file, "\t%s *self = %s%s(base);\n", class->cname, class->namespace->upper_case_cname, class->upper_case_cname); - } - - generator->sym = vala_symbol_new (VALA_SYMBOL_TYPE_BLOCK); - generator->sym->stmt = method->body; - - ValaSymbol *sym; - GList *pl; - - for (pl = method->formal_parameters; pl != NULL; pl = pl->next) { - ValaFormalParameter *param = pl->data; - - sym = vala_symbol_new (VALA_SYMBOL_TYPE_LOCAL_VARIABLE); - g_hash_table_insert (generator->sym->symbol_table, param->name, sym); - sym->typeref = param->type; - } - - vala_code_generator_process_block (generator, method->body); - - if (method->modifiers & VALA_MODIFIER_OVERRIDE) { - fprintf (generator->c_file, "}\n"); - } - } - - fprintf (generator->c_file, "\n"); - - if (method->modifiers & (VALA_MODIFIER_ABSTRACT | VALA_MODIFIER_VIRTUAL)) { - fprintf (generator->c_file, "%s\n", method->cdecl1); - fprintf (generator->c_file, "%s (%s)\n", method->cname, method->cparameters); - fprintf (generator->c_file, "{\n"); - fprintf (generator->c_file, "\t"); - if (method->return_type->symbol->type != VALA_SYMBOL_TYPE_VOID) { - fprintf (generator->c_file, "return "); - } - fprintf (generator->c_file, "%s%s_GET_CLASS (self)->%s (self", ns_upper, upper_case, method->name); - - GList *pl; - - for (pl = method->formal_parameters; pl != NULL; pl = pl->next) { - ValaFormalParameter *param = pl->data; - - fprintf (generator->c_file, ", %s", param->name); - } - - fprintf (generator->c_file, ");\n"); - fprintf (generator->c_file, "}\n"); - fprintf (generator->c_file, "\n"); - } - - if ((method->modifiers & VALA_MODIFIER_STATIC) && strcmp (method->name, "main") == 0 && strcmp (method->return_type->type_name, "int") == 0) { - if (g_list_length (method->formal_parameters) == 2) { - /* main method */ - - fprintf (generator->c_file, "int\n"); - fprintf (generator->c_file, "main (int argc, char **argv)\n"); - fprintf (generator->c_file, "{\n"); - fprintf (generator->c_file, "\tg_type_init ();\n"); - fprintf (generator->c_file, "\treturn %s (argc, argv);\n", method->cname); - fprintf (generator->c_file, "}\n"); - fprintf (generator->c_file, "\n"); - } - } - } - fprintf (generator->h_file, "\n"); - - /* properties */ - if (class->properties != NULL) { - fprintf (generator->c_file, "enum {\n"); - fprintf (generator->c_file, "\t%s%s_DUMMY_PROPERTY,\n", ns_upper, upper_case); - for (l = class->properties; l != NULL; l = l->next) { - ValaProperty *prop = l->data; - fprintf (generator->c_file, "\t%s%s_%s,\n", ns_upper, upper_case, g_ascii_strup (prop->name, -1)); - } - fprintf (generator->c_file, "};\n"); - - /* getter / setter */ - for (l = class->properties; l != NULL; l = l->next) { - ValaProperty *prop = l->data; - - /* getter */ - if (prop->get_statement != NULL) { - fprintf (generator->h_file, "%s %s%s_get_%s (%s *self);\n", get_cname_for_type_reference (prop->return_type, FALSE, prop->location), ns_lower, lower_case, prop->name, class->cname); - fprintf (generator->c_file, "%s\n", get_cname_for_type_reference (prop->return_type, FALSE, prop->location)); - fprintf (generator->c_file, "%s%s_get_%s (%s *self)\n", ns_lower, lower_case, prop->name, class->cname); - - generator->sym = vala_symbol_new (VALA_SYMBOL_TYPE_BLOCK); - generator->sym->stmt = prop->get_statement; - - vala_code_generator_process_statement (generator, prop->get_statement); - } - - /* setter */ - if (prop->set_statement != NULL) { - fprintf (generator->h_file, "void %s%s_set_%s (%s *self, %svalue);\n", ns_lower, lower_case, prop->name, class->cname, get_cname_for_type_reference (prop->return_type, FALSE, prop->location)); - fprintf (generator->c_file, "void\n"); - fprintf (generator->c_file, "%s%s_set_%s (%s *self, %svalue)\n", ns_lower, lower_case, prop->name, class->cname, get_cname_for_type_reference (prop->return_type, FALSE, prop->location)); - - generator->sym = vala_symbol_new (VALA_SYMBOL_TYPE_BLOCK); - generator->sym->stmt = prop->set_statement; - - ValaSymbol *sym = vala_symbol_new (VALA_SYMBOL_TYPE_LOCAL_VARIABLE); - g_hash_table_insert (generator->sym->symbol_table, "value", sym); - sym->typeref = prop->return_type; - - vala_code_generator_process_statement (generator, prop->set_statement); - } - } - - /* override get_property */ - fprintf (generator->c_file, "static void\n"); - fprintf (generator->c_file, "%s%s_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)\n", ns_lower, lower_case); - fprintf (generator->c_file, "{\n"); - fprintf (generator->c_file, "\t%s *self = (%s *) object;\n", class->cname, class->cname); - fprintf (generator->c_file, "\tswitch (property_id) {\n"); - for (l = class->properties; l != NULL; l = l->next) { - ValaProperty *prop = l->data; - if (prop->get_statement == NULL) { - continue; - } - fprintf (generator->c_file, "\tcase %s%s_%s:\n", ns_upper, upper_case, g_ascii_strup (prop->name, -1)); - - if (strcmp (prop->return_type->type_name, "string") == 0) { - fprintf (generator->c_file, "\t\tg_value_set_string"); - } else if (prop->return_type->symbol->type == VALA_SYMBOL_TYPE_ENUM || strcmp (prop->return_type->type_name, "int") == 0) { - fprintf (generator->c_file, "\t\tg_value_set_int"); - } else if (strcmp (prop->return_type->type_name, "bool") == 0) { - fprintf (generator->c_file, "\t\tg_value_set_boolean"); - } else if (prop->return_type->symbol->type == VALA_SYMBOL_TYPE_CLASS) { - fprintf (generator->c_file, "\t\tg_value_set_object"); - } else { - fprintf (generator->c_file, "\t\tg_value_set_pointer"); - } - fprintf (generator->c_file, " (value, %s%s_get_%s (self));\n", ns_lower, lower_case, prop->name); - fprintf (generator->c_file, "\t\tbreak;\n"); - } - fprintf (generator->c_file, "\tdefault:\n"); - fprintf (generator->c_file, "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID(object,property_id,pspec);\n"); - fprintf (generator->c_file, "\t\tbreak;\n"); - fprintf (generator->c_file, "\t}\n"); - fprintf (generator->c_file, "}\n"); - - /* override set_property */ - fprintf (generator->c_file, "static void\n"); - fprintf (generator->c_file, "%s%s_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)\n", ns_lower, lower_case); - fprintf (generator->c_file, "{\n"); - fprintf (generator->c_file, "\t%s *self = (%s *) object;\n", class->cname, class->cname); - fprintf (generator->c_file, "\tswitch (property_id) {\n"); - for (l = class->properties; l != NULL; l = l->next) { - ValaProperty *prop = l->data; - if (prop->set_statement == NULL) { - continue; - } - fprintf (generator->c_file, "\tcase %s%s_%s:\n", ns_upper, upper_case, g_ascii_strup (prop->name, -1)); - - fprintf (generator->c_file, "\t%s%s_set_%s (self, ", ns_lower, lower_case, prop->name); - if (strcmp (prop->return_type->type_name, "string") == 0) { - fprintf (generator->c_file, "g_value_dup_string (value)"); - } else if (prop->return_type->symbol->type == VALA_SYMBOL_TYPE_ENUM || strcmp (prop->return_type->type_name, "int") == 0) { - fprintf (generator->c_file, "g_value_get_int (value)"); - } else if (strcmp (prop->return_type->type_name, "bool") == 0) { - fprintf (generator->c_file, "g_value_get_boolean (value)"); - } else if (prop->return_type->symbol->type == VALA_SYMBOL_TYPE_CLASS) { - fprintf (generator->c_file, "g_value_get_object (value)"); - } else { - fprintf (generator->c_file, "g_value_get_pointer (value)"); - } - fprintf (generator->c_file, ");\n"); - fprintf (generator->c_file, "\t\tbreak;\n"); - } - fprintf (generator->c_file, "\tdefault:\n"); - fprintf (generator->c_file, "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID(object,property_id,pspec);\n"); - fprintf (generator->c_file, "\t\tbreak;\n"); - fprintf (generator->c_file, "\t}\n"); - fprintf (generator->c_file, "}\n"); - } - - /* constructors */ - fprintf (generator->c_file, "static void\n"); - fprintf (generator->c_file, "%s%s_init (%s%s *self)\n", ns_lower, lower_case, namespace->name, class->name); - fprintf (generator->c_file, "{\n"); - - if (class->has_private_fields) { - fprintf (generator->c_file, "\tself->priv = %s%s_GET_PRIVATE (self);\n", ns_upper, upper_case); - } - - /* initialize all fields */ - for (l = class->fields; l != NULL; l = l->next) { - ValaField *field = l->data; - ValaExpression *expr = field->declaration_statement->variable_declaration->declarator->initializer; - - if ((field->modifiers & VALA_MODIFIER_STATIC) != 0 || expr == NULL) { - continue; - } else if ((field->modifiers & VALA_MODIFIER_PUBLIC) != 0) { - fprintf (generator->c_file, "\tself->%s = ", field->declaration_statement->variable_declaration->declarator->name); - } else if ((field->modifiers & VALA_MODIFIER_PRIVATE) != 0) { - fprintf (generator->c_file, "\tself->priv->%s = ", field->declaration_statement->variable_declaration->declarator->name); - } - vala_code_generator_process_expression (generator, expr); - fprintf (generator->c_file, ";\n"); - } - - if (class->init_method != NULL) { - generator->sym = vala_symbol_new (VALA_SYMBOL_TYPE_BLOCK); - generator->sym->stmt = class->init_method->body; - - vala_code_generator_process_block (generator, class->init_method->body); - } - - fprintf (generator->c_file, "}\n"); - fprintf (generator->c_file, "\n"); - - fprintf (generator->c_file, "static void\n"); - fprintf (generator->c_file, "%s%s_class_init (%s%sClass *klass)\n", ns_lower, lower_case, namespace->name, class->name); - fprintf (generator->c_file, "{\n"); - if (class->has_private_fields) { - fprintf (generator->c_file, "\tg_type_class_add_private (klass, sizeof (%sPrivate));\n", g_strdup_printf ("%s%s", class->namespace->name, class->name)); - } - - /* initialize all static fields */ - for (l = class->fields; l != NULL; l = l->next) { - ValaField *field = l->data; - ValaExpression *expr = field->declaration_statement->variable_declaration->declarator->initializer; - - if ((field->modifiers & VALA_MODIFIER_STATIC) == 0 || expr == NULL) { - continue; - } else if ((field->modifiers & VALA_MODIFIER_PUBLIC) != 0) { - fprintf (generator->c_file, "\tklass->%s = ", field->declaration_statement->variable_declaration->declarator->name); - } else if ((field->modifiers & VALA_MODIFIER_PRIVATE) != 0) { - /* no private support for now */ - continue; - } - vala_code_generator_process_expression (generator, expr); - fprintf (generator->c_file, ";\n"); - } - - /* chain virtual functions */ - for (l = class->methods; l != NULL; l = l->next) { - ValaMethod *method = l->data; - - if (method->modifiers & (VALA_MODIFIER_VIRTUAL | VALA_MODIFIER_OVERRIDE)) { - fprintf (generator->c_file, "\t"); - if (method->modifiers & VALA_MODIFIER_OVERRIDE) { - fprintf (generator->c_file, "%s%s_CLASS (klass)", method->virtual_super_class->namespace->upper_case_cname, method->virtual_super_class->upper_case_cname); - } else { - fprintf (generator->c_file, "klass"); - } - fprintf (generator->c_file, "->%s = %s%s_real_%s;\n", method->name, ns_lower, lower_case, method->name); - } - } - - if (class->properties != NULL) { - fprintf (generator->c_file, "\tG_OBJECT_CLASS(klass)->set_property = %s%s_set_property;\n", ns_lower, lower_case); - fprintf (generator->c_file, "\tG_OBJECT_CLASS(klass)->get_property = %s%s_get_property;\n", ns_lower, lower_case); - for (l = class->properties; l != NULL; l = l->next) { - ValaProperty *prop = l->data; - fprintf (generator->c_file, "\tg_object_class_install_property (G_OBJECT_CLASS(klass), %s%s_%s, ", ns_upper, upper_case, g_ascii_strup (prop->name, -1)); - - /* paramspec */ - if (strcmp (prop->return_type->type_name, "string") == 0) { - fprintf (generator->c_file, "g_param_spec_string"); - fprintf (generator->c_file, " (\"%s\", \"foo\", \"bar\", NULL, G_PARAM_CONSTRUCT | G_PARAM_READWRITE)", prop->name); - } else if (prop->return_type->symbol->type == VALA_SYMBOL_TYPE_ENUM || strcmp (prop->return_type->type_name, "int") == 0) { - fprintf (generator->c_file, "g_param_spec_int"); - fprintf (generator->c_file, " (\"%s\", \"foo\", \"bar\", G_MININT, G_MAXINT, 0, G_PARAM_CONSTRUCT | G_PARAM_READWRITE)", prop->name); - } else if (strcmp (prop->return_type->type_name, "bool") == 0) { - fprintf (generator->c_file, "g_param_spec_boolean"); - fprintf (generator->c_file, " (\"%s\", \"foo\", \"bar\", FALSE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE)", prop->name); - } else if (prop->return_type->symbol->type == VALA_SYMBOL_TYPE_CLASS) { - fprintf (generator->c_file, "g_param_spec_object"); - fprintf (generator->c_file, " (\"%s\", \"foo\", \"bar\", %sTYPE_%s, G_PARAM_CONSTRUCT | G_PARAM_READWRITE)", prop->name, prop->return_type->symbol->class->namespace->upper_case_cname, prop->return_type->symbol->class->upper_case_cname); - } else { - fprintf (generator->c_file, "g_param_spec_pointer"); - fprintf (generator->c_file, " (\"%s\", \"foo\", \"bar\", G_PARAM_CONSTRUCT | G_PARAM_READWRITE)", prop->name); - } - - fprintf (generator->c_file, ");\n"); - } - } - - if (class->class_init_method != NULL) { - generator->sym = vala_symbol_new (VALA_SYMBOL_TYPE_BLOCK); - generator->sym->stmt = class->class_init_method->body; - - vala_code_generator_process_block (generator, class->class_init_method->body); - } - - fprintf (generator->c_file, "}\n"); - fprintf (generator->c_file, "\n"); -} - -static void -vala_code_generator_process_virtual_method_pointers (ValaCodeGenerator *generator, ValaClass *class) -{ - GList *l; - gboolean first = TRUE; - - char *ns_lower; - char *ns_upper; - - ValaNamespace *namespace = class->namespace; - - ns_lower = namespace->lower_case_cname; - ns_upper = namespace->upper_case_cname; - - char *lower_case = class->lower_case_cname; - char *upper_case = class->upper_case_cname; - - for (l = class->methods; l != NULL; l = l->next) { - ValaMethod *method = l->data; - - if ((method->modifiers & (VALA_MODIFIER_ABSTRACT | VALA_MODIFIER_VIRTUAL)) == 0) { - continue; - } - - if (first) { - fprintf (generator->h_file, "\n"); - fprintf (generator->h_file, "\t/* virtual methods */\n"); - } else { - first = FALSE; - } - - fprintf (generator->h_file, "\t%s(*%s) (%s);\n", get_cname_for_type_reference (method->return_type, FALSE, method->location), method->name, method->cparameters); - } -} - -static void -vala_code_generator_process_class1 (ValaCodeGenerator *generator, ValaClass *class) -{ - ValaNamespace *namespace = class->namespace; - - generator->class = class; - - char *camel_case; - char *ns_lower; - char *ns_upper; - GList *l; - - camel_case = class->cname; - ns_lower = namespace->lower_case_cname; - ns_upper = namespace->upper_case_cname; - - char *lower_case = class->lower_case_cname; - char *upper_case = class->upper_case_cname; - - /* type macros */ - fprintf (generator->h_file, "#define %sTYPE_%s\t(%s%s_get_type ())\n", ns_upper, upper_case, ns_lower, lower_case); - fprintf (generator->h_file, "#define %s%s(obj)\t(G_TYPE_CHECK_INSTANCE_CAST ((obj), %sTYPE_%s, %s))\n", ns_upper, upper_case, ns_upper, upper_case, camel_case); - fprintf (generator->h_file, "#define %s%s_CLASS(klass)\t(G_TYPE_CHECK_CLASS_CAST ((klass), %sTYPE_%s, %sClass))\n", ns_upper, upper_case, ns_upper, upper_case, camel_case); - fprintf (generator->h_file, "#define %sIS_%s(obj)\t(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %sTYPE_%s))\n", ns_upper, upper_case, ns_upper, upper_case); - fprintf (generator->h_file, "#define %sIS_%s_CLASS(klass)\t(G_TYPE_CHECK_CLASS_TYPE ((klass), %sTYPE_%s))\n", ns_upper, upper_case, ns_upper, upper_case); - fprintf (generator->h_file, "#define %s%s_GET_CLASS(obj)\t(G_TYPE_INSTANCE_GET_CLASS ((obj), %sTYPE_%s, %sClass))\n", ns_upper, upper_case, ns_upper, upper_case, camel_case); - fprintf (generator->h_file, "\n"); - - /* structs */ - fprintf (generator->h_file, "#ifndef _TYPE_%s%s\n", class->namespace->upper_case_cname, class->upper_case_cname); - fprintf (generator->h_file, "#define _TYPE_%s%s\n", class->namespace->upper_case_cname, class->upper_case_cname); - fprintf (generator->h_file, "typedef struct _%s %s;\n", camel_case, camel_case); - fprintf (generator->h_file, "typedef struct _%sClass %sClass;\n", camel_case, camel_case); - fprintf (generator->h_file, "#endif\n"); - fprintf (generator->h_file, "typedef struct _%sPrivate %sPrivate;\n", camel_case, camel_case); - fprintf (generator->h_file, "\n"); - - vala_code_generator_process_methods1 (generator, class); - - /* private structure */ - fprintf (generator->c_file, "struct _%sPrivate {\n", camel_case); - /* private fields */ - for (l = get_fields_by_flag (class, VALA_MODIFIER_PRIVATE); l != NULL; l = l->next) { - class->has_private_fields = TRUE; - ValaField *field = l->data; - ValaTypeReference *type = field->declaration_statement->variable_declaration->type; - - fprintf (generator->c_file, "\t%s%s;\n", get_cname_for_type_reference (type, FALSE, field->declaration_statement->location),field->declaration_statement->variable_declaration->declarator->name); - } - if (!class->has_private_fields) { - /* silence gcc */ - fprintf (generator->c_file, "\tint dummy;\n"); - } - fprintf (generator->c_file, "};\n", camel_case); - fprintf (generator->c_file, "\n"); - /* get private macro */ - fprintf (generator->c_file, "#define %s%s_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), %sTYPE_%s, %sPrivate))\n\n", ns_upper, upper_case, ns_upper, upper_case, camel_case); - - /* private static fields */ - for (l = get_fields_by_flag (class, VALA_MODIFIER_PRIVATE | VALA_MODIFIER_STATIC); l != NULL; l = l->next) { - ValaField *field = l->data; - ValaTypeReference *type = field->declaration_statement->variable_declaration->type; - - fprintf (generator->c_file, "static %s%s;\n", get_cname_for_type_reference (type, FALSE, field->declaration_statement->location),field->declaration_statement->variable_declaration->declarator->name); - } - fprintf (generator->c_file, "\n"); -} - -static void -vala_code_generator_process_struct1 (ValaCodeGenerator *generator, ValaStruct *struct_) -{ - ValaNamespace *namespace = struct_->namespace; - - generator->struct_ = struct_; - - char *camel_case; - char *ns_lower; - char *ns_upper; - GList *l; - - camel_case = struct_->cname; - ns_lower = namespace->lower_case_cname; - ns_upper = namespace->upper_case_cname; - - char *lower_case = struct_->lower_case_cname; - char *upper_case = struct_->upper_case_cname; - - /* structs */ - fprintf (generator->h_file, "typedef struct _%s %s;\n", camel_case, camel_case); - fprintf (generator->h_file, "\n"); - - vala_code_generator_process_struct_methods1 (generator, struct_); -} - -static void -vala_code_generator_process_enum1 (ValaCodeGenerator *generator, ValaEnum *enum_) -{ - ValaNamespace *namespace = enum_->namespace; - - char *camel_case; - char *ns_upper; - GList *l; - - camel_case = enum_->cname; - ns_upper = namespace->upper_case_cname; - - char *upper_case = enum_->upper_case_cname; - - fprintf (generator->h_file, "typedef enum {\n"); - for (l = enum_->values; l != NULL; l = l->next) { - ValaEnumValue *val = l->data; - - fprintf (generator->h_file, "\t%s,\n", val->cname); - } - - fprintf (generator->h_file, "} %s;\n", camel_case); - fprintf (generator->h_file, "\n"); -} - -static void -vala_code_generator_process_class2 (ValaCodeGenerator *generator, ValaClass *class) -{ - ValaNamespace *namespace = class->namespace; - - generator->class = class; - - char *camel_case; - char *ns_lower; - char *ns_upper; - GList *l; - - camel_case = g_strdup_printf ("%s%s", namespace->name, class->name); - ns_lower = namespace->lower_case_cname; - ns_upper = namespace->upper_case_cname; - - char *lower_case = class->lower_case_cname; - char *upper_case = class->upper_case_cname; - - /* structs */ - fprintf (generator->h_file, "struct _%s {\n", camel_case); - fprintf (generator->h_file, "\t%s parent;\n", class->base_class->cname); - fprintf (generator->h_file, "\t%sPrivate *priv;\n", camel_case); - /* public fields */ - for (l = get_fields_by_flag (class, VALA_MODIFIER_PUBLIC); l != NULL; l = l->next) { - ValaField *field = l->data; - ValaTypeReference *type = field->declaration_statement->variable_declaration->type; - - fprintf (generator->h_file, "\t%s%s;\n", get_cname_for_type_reference (type, FALSE, field->declaration_statement->location),field->declaration_statement->variable_declaration->declarator->name); - } - - fprintf (generator->h_file, "};\n"); - fprintf (generator->h_file, "\n"); - - fprintf (generator->h_file, "struct _%sClass {\n", camel_case); - fprintf (generator->h_file, "\t%sClass parent;\n", class->base_class->cname); - /* public static fields */ - for (l = get_fields_by_flag (class, VALA_MODIFIER_PUBLIC | VALA_MODIFIER_STATIC); l != NULL; l = l->next) { - ValaField *field = l->data; - ValaTypeReference *type = field->declaration_statement->variable_declaration->type; - - fprintf (generator->h_file, "\t%s%s;\n", get_cname_for_type_reference (type, FALSE, field->declaration_statement->location),field->declaration_statement->variable_declaration->declarator->name); - } - - vala_code_generator_process_virtual_method_pointers (generator, class); - - fprintf (generator->h_file, "};\n"); - fprintf (generator->h_file, "\n"); - - /* function declarations */ - fprintf (generator->h_file, "GType %s%s_get_type () G_GNUC_CONST;\n", ns_lower, lower_case); - fprintf (generator->h_file, "\n"); - - vala_code_generator_process_constants (generator, class); - - vala_code_generator_process_methods2 (generator, class); - - /* type initialization function */ - fprintf (generator->c_file, "GType\n"); - fprintf (generator->c_file, "%s%s_get_type ()\n", ns_lower, lower_case); - fprintf (generator->c_file, "{\n"); - fprintf (generator->c_file, "\tstatic GType g_define_type_id = 0;\n"); - fprintf (generator->c_file, "\tif (G_UNLIKELY (g_define_type_id == 0)) {\n"); - fprintf (generator->c_file, "\t\tstatic const GTypeInfo g_define_type_info = {\n"); - fprintf (generator->c_file, "\t\t\tsizeof (%sClass),\n", camel_case); - fprintf (generator->c_file, "\t\t\t(GBaseInitFunc) NULL,\n"); - fprintf (generator->c_file, "\t\t\t(GBaseFinalizeFunc) NULL,\n"); - fprintf (generator->c_file, "\t\t\t(GClassInitFunc) %s%s_class_init,\n", ns_lower, lower_case); - fprintf (generator->c_file, "\t\t\t(GClassFinalizeFunc) NULL,\n"); - fprintf (generator->c_file, "\t\t\tNULL, /* class_data */\n"); - fprintf (generator->c_file, "\t\t\tsizeof (%s),\n", camel_case); - fprintf (generator->c_file, "\t\t\t0, /* n_preallocs */\n"); - fprintf (generator->c_file, "\t\t\t(GInstanceInitFunc) %s%s_init,\n", ns_lower, lower_case); - fprintf (generator->c_file, "\t\t};\n"); - - fprintf (generator->c_file, "\t\tg_define_type_id = g_type_register_static (%sTYPE_%s, \"%s\", &g_define_type_info, 0);\n", class->base_class->namespace->upper_case_cname, class->base_class->upper_case_cname, camel_case); - - /* FIXME: add interfaces */ - fprintf (generator->c_file, "\t}\n"); - fprintf (generator->c_file, "\treturn g_define_type_id;\n"); - fprintf (generator->c_file, "}\n"); - fprintf (generator->c_file, "\n"); -} - -static void -vala_code_generator_process_namespace1 (ValaCodeGenerator *generator, ValaNamespace *namespace) -{ - GList *l; - for (l = namespace->classes; l != NULL; l = l->next) { - vala_code_generator_process_class1 (generator, l->data); - } - for (l = namespace->structs; l != NULL; l = l->next) { - vala_code_generator_process_struct1 (generator, l->data); - } - for (l = namespace->enums; l != NULL; l = l->next) { - vala_code_generator_process_enum1 (generator, l->data); - } - for (l = namespace->methods; l != NULL; l = l->next) { - vala_code_generator_process_ns_method (generator, namespace, l->data); - } -} - -static void -vala_code_generator_process_namespace2 (ValaCodeGenerator *generator, ValaNamespace *namespace) -{ - GList *l; - for (l = namespace->classes; l != NULL; l = l->next) { - vala_code_generator_process_class2 (generator, l->data); - } -} - -static void -vala_code_generator_process_dep_type (ValaCodeGenerator *generator, FILE *f, ValaSymbol *dep_type, GList **dep_files) -{ - ValaSourceFile *dep_file; - ValaNamespace *namespace; - if (dep_type->type == VALA_SYMBOL_TYPE_CLASS) { - namespace = dep_type->class->namespace; - } else if (dep_type->type == VALA_SYMBOL_TYPE_STRUCT) { - namespace = dep_type->struct_->namespace; - } else if (dep_type->type == VALA_SYMBOL_TYPE_ENUM) { - namespace = dep_type->enum_->namespace; - } else { - err (NULL, "internal error: dependant type is neither class nor struct"); - } - if (namespace->name == NULL || strlen (namespace->name) == 0) { - /* might be global namespace of imported library, don't use stub header */ - /* FIXME: mark source file as appropriate so non-imported types in global namespace work */ - return; - } - if (namespace->import) { - /* imported namespace, don't use stub header */ - /* FIXME: include real header instead */ - - if (namespace->include_filename != NULL) { - fprintf (f, "#include <%s>\n", namespace->include_filename); - } - - return; - } - dep_file = namespace->source_file; - - if (dep_file == NULL) { - /* type without source file, ignore */ - return; - } - - GList *fl; - for (fl = *dep_files; fl != NULL; fl = fl->next) { - if (fl->data == dep_file) { - dep_file = NULL; - break; - } - } - if (dep_file == NULL) { - /* file already included, ignore */ - return; - } - - *dep_files = g_list_prepend (*dep_files, dep_file); - - char *dep_basename = g_strdup (dep_file->filename); - dep_basename[strlen (dep_basename) - strlen (".vala")] = '\0'; - - fprintf (f, "#include <%s.h>\n", dep_basename); -} - -static void -vala_code_generator_process_source_file (ValaCodeGenerator *generator, ValaSourceFile *source_file) -{ - char *basename = g_strdup (source_file->filename); - basename[strlen (basename) - strlen (".vala")] = '\0'; - - /* FIXME: use output directory */ - - char *c_filename = g_strdup_printf ("%s.c", basename); - char *h_filename = g_strdup_printf ("%s.h", basename); - - char *header_define = filename_to_define (h_filename); - - /* - * FIXME: (optionally) skip source file if c_file and h_file already - * exist and their mtime is >= mtime of source_file - * => reduces unnecessary rebuilds - * - * to be really safe, ensure that output would be identical - */ - - generator->c_file = fopen (c_filename, "w"); - generator->h_file = fopen (h_filename, "w"); - - fprintf (generator->h_file, "#ifndef __%s__\n", header_define); - fprintf (generator->h_file, "#define __%s__\n", header_define); - fprintf (generator->h_file, "\n"); - - fprintf (generator->h_file, "#include \n"); - fprintf (generator->h_file, "#include \n"); - fprintf (generator->h_file, "#include \n"); - fprintf (generator->h_file, "\n"); - - fprintf (generator->h_file, "G_BEGIN_DECLS\n"); - fprintf (generator->h_file, "\n"); - - /* FIXME: fix leak */ - fprintf (generator->c_file, "#include \"%s\"\n", g_path_get_basename (h_filename)); - fprintf (generator->c_file, "\n"); - - vala_code_generator_process_namespace1 (generator, source_file->root_namespace); - GList *l; - - for (l = source_file->namespaces; l != NULL; l = l->next) { - ValaNamespace *ns = l->data; - - vala_code_generator_process_namespace1 (generator, ns); - } - - fprintf (generator->h_file, "G_END_DECLS\n"); - fprintf (generator->h_file, "\n"); - - /* FIXME: add include directives for base class and other depending classes */ - /* use <> notation, assume layout in package include directory is the - * same as in the source directory. compiler should accept parameter to - * specify include root directory if something different than current - * working directory is needed */ - - GList *dep_files = NULL; - - for (l = source_file->namespaces; l != NULL; l = l->next) { - ValaNamespace *ns = l->data; - - if (ns->import) - continue; - - GList *cl; - for (cl = ns->classes; cl != NULL; cl = cl->next) { - ValaClass *c = cl->data; - if (c->base_class != NULL) { - vala_code_generator_process_dep_type (generator, generator->h_file, c->base_class->symbol, &dep_files); - } - } - } - - for (l = source_file->dep_types; l != NULL; l = l->next) { - ValaSymbol *sym = l->data; - if (sym->type == VALA_SYMBOL_TYPE_CLASS && !sym->class->namespace->import) { - ValaClass *class = sym->class; - fprintf (generator->h_file, "#ifndef _TYPE_%s%s\n", class->namespace->upper_case_cname, class->upper_case_cname); - fprintf (generator->h_file, "#define _TYPE_%s%s\n", class->namespace->upper_case_cname, class->upper_case_cname); - fprintf (generator->h_file, "typedef struct _%s %s;\n", class->cname, class->cname); - fprintf (generator->h_file, "typedef struct _%sClass %sClass;\n", class->cname, class->cname); - fprintf (generator->h_file, "#endif\n"); - } else if (sym->type == VALA_SYMBOL_TYPE_ENUM) { - vala_code_generator_process_dep_type (generator, generator->h_file, l->data, &dep_files); - } - vala_code_generator_process_dep_type (generator, generator->c_file, l->data, &dep_files); - } - fprintf (generator->h_file, "\n"); - - fprintf (generator->h_file, "G_BEGIN_DECLS\n"); - fprintf (generator->h_file, "\n"); - - vala_code_generator_process_namespace2 (generator, source_file->root_namespace); - - for (l = source_file->namespaces; l != NULL; l = l->next) { - ValaNamespace *ns = l->data; - - if (!ns->import) { - vala_code_generator_process_namespace2 (generator, ns); - } - } - - fprintf (generator->h_file, "G_END_DECLS\n"); - fprintf (generator->h_file, "\n"); - - fprintf (generator->h_file, "#endif /* __%s__ */\n", header_define); - - fclose (generator->c_file); - fclose (generator->h_file); - - generator->c_file = NULL; - generator->h_file = NULL; -} - -void -vala_code_generator_run (ValaCodeGenerator *generator) -{ - ValaSourceFile *source_file; - - GList *l; - - for (l = generator->context->source_files; l != NULL; l = l->next) { - vala_code_generator_process_source_file (generator, l->data); - } -} - -void -vala_code_generator_free (ValaCodeGenerator *generator) -{ - g_free (generator); -} diff --git a/vala/valac/generator.h b/vala/valac/generator.h deleted file mode 100644 index 88008c7..0000000 --- a/vala/valac/generator.h +++ /dev/null @@ -1,39 +0,0 @@ -/* generator.h - * - * Copyright (C) 2006 Jürg Billeter - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: - * Jürg Billeter - */ - -#include - -typedef struct _ValaCodeGenerator ValaCodeGenerator; - -struct _ValaCodeGenerator { - ValaContext *context; - const char *directory; - FILE *c_file; - FILE *h_file; - ValaSymbol *sym; /* current block */ - ValaClass *class; /* current class */ - ValaStruct *struct_; /* current struct */ -}; - -ValaCodeGenerator *vala_code_generator_new (ValaContext *context); -void vala_code_generator_run (ValaCodeGenerator *generator); -void vala_code_generator_free (ValaCodeGenerator *generator); diff --git a/vala/valac/parser.y b/vala/valac/parser.y deleted file mode 100644 index 83f826a..0000000 --- a/vala/valac/parser.y +++ /dev/null @@ -1,2106 +0,0 @@ -/* parser.y - * - * Copyright (C) 2006 Jürg Billeter, Raffaele Sandrini - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: - * Jürg Billeter - * Raffaele Sandrini - */ - -%{ -#include -#include -#include - -#include - -#include "context.h" - -static char * -camel_case_to_lower_case (const char *camel_case) -{ - char *str = g_malloc0 (2 * strlen (camel_case)); - const char *i = camel_case; - char *p = str; - - /* - * This function tries to find word boundaries in camel case with the - * following constraints - * - words always begin with an upper case character - * - the remaining characters are either all upper case or all lower case - * - words have at least two characters - */ - - while (*i != '\0') { - if (isupper (*i)) { - /* current character is upper case */ - if (i != camel_case) { - /* we're not at the beginning */ - const char *t = i - 1; - gboolean prev_upper = isupper (*t); - t = i + 1; - gboolean next_upper = isupper (*t); - if (!prev_upper || (*t != '\0' && !next_upper)) { - /* previous character wasn't upper case */ - t = p - 2; - if (p - str != 1 && *t != '_') { - /* we're not creating 1 character words */ - *p = '_'; - p++; - } - } - } - } - - *p = tolower (*i); - i++; - p++; - } - - return str; -} - -static char * -camel_case_to_upper_case (const char *camel_case) -{ - char *str = camel_case_to_lower_case (camel_case); - - char *p; - - for (p = str; *p != '\0'; p++) { - *p = toupper (*p); - } - - return str; -} - -static char * -eval_string (const char *cstring) -{ - char *ret = g_strdup (cstring + 1); - ret[strlen (ret) - 1] = '\0'; - return ret; -} - -static ValaSourceFile *current_source_file; -static ValaNamespace *current_namespace; -static ValaClass *current_class; -static ValaStruct *current_struct; -static ValaMethod *current_method; - -ValaLocation *get_location (int lineno, int colno) -{ - ValaLocation *loc = g_new0 (ValaLocation, 1); - loc->source_file = current_source_file; - loc->lineno = lineno; - loc->colno = colno; - return loc; -} - -#define current_location(token) get_location (token.first_line, token.first_column) -%} - -%defines -%locations -%error-verbose -%pure_parser -%glr-parser -%union { - int num; - char *str; - gboolean bool; - GList *list; - ValaTypeReference *type_reference; - ValaFormalParameter *formal_parameter; - ValaMethod *method; - ValaStruct *struct_; - ValaEnum *enum_; - ValaFlags *flags; - ValaStatement *statement; - ValaVariableDeclaration *variable_declaration; - ValaVariableDeclarator *variable_declarator; - ValaExpression *expression; - ValaField *field; - ValaConstant *constant; - ValaProperty *property; - ValaNamedArgument *named_argument; - ValaEnumValue *enum_value; - ValaFlagsValue *flags_value; - ValaAnnotation *annotation; -} - -%token OPEN_BRACE "{" -%token CLOSE_BRACE "}" -%token OPEN_PARENS "(" -%token OPEN_CAST_PARENS "cast (" -%token CLOSE_PARENS ")" -%token OPEN_BRACKET "[" -%token CLOSE_BRACKET "]" -%token DOT "." -%token COLON ":" -%token COMMA "," -%token SEMICOLON ";" -%token HASH "#" - -%token ASSIGN_BITWISE_OR "|=" - -%token OP_INC "++" -%token OP_DEC "--" -%token OP_EQ "==" -%token OP_NE "!=" -%token OP_LE "<=" -%token OP_GE ">=" -%token OP_LT "<" -%token OP_GT ">" -%token OP_NEG "!" -%token OP_OR "||" -%token OP_AND "&&" -%token BITWISE_OR "|" -%token BITWISE_AND "&" - -%token ASSIGN "=" -%token PLUS "+" -%token MINUS "-" -%token STAR "*" -%token DIV "/" - -%token ABSTRACT "abstract" -%token CLASS "class" -%token CONST "const" -%token CONSTRUCT "construct" -%token ELSE "else" -%token ENUM "enum" -%token VALA_FALSE "false" -%token FLAGS "flags" -%token FOR "for" -%token FOREACH "foreach" -%token GET "get" -%token IF "if" -%token IN "in" -%token INTERFACE "interface" -%token IS "is" -%token NAMESPACE "namespace" -%token VALA_NULL "null" -%token OUT "out" -%token OVERRIDE "override" -%token PUBLIC "public" -%token PRIVATE "private" -%token REF "ref" -%token SET "set" -%token STATIC "static" -%token STRUCT "struct" -%token READONLY "readonly" -%token RETURN "return" -%token THIS "this" -%token VALA_TRUE "true" -%token USING "using" -%token VAR "var" -%token VIRTUAL "virtual" -%token WEAK "weak" -%token WHILE "while" - -%token IDENTIFIER "identifier" -%token LITERAL_CHARACTER "character" -%token LITERAL_INTEGER "integer" -%token LITERAL_STRING "string" - -%type opt_type_parameter_list -%type type_parameter_list -%type type_parameters -%type opt_type_argument_list -%type type_argument_list -%type type_arguments -%type opt_class_base -%type class_base -%type type_list -%type opt_formal_parameter_list -%type formal_parameter_list -%type fixed_parameters -%type opt_statement_list -%type statement_list -%type opt_argument_list -%type argument_list -%type opt_named_argument_list -%type named_argument_list -%type opt_statement_expression_list -%type statement_expression_list -%type opt_variable_initializer_list -%type variable_initializer_list -%type opt_modifiers -%type modifiers -%type modifier -%type opt_parameter_modifier -%type parameter_modifier -%type opt_at -%type opt_brackets -%type boolean_literal -%type type_name -%type variable_initializer -%type opt_expression -%type expression -%type additive_expression -%type multiplicative_expression -%type unary_expression -%type cast_expression -%type assignment -%type primary_expression -%type literal -%type simple_name -%type parenthesized_expression -%type member_access -%type invocation_expression -%type element_access -%type this_access -%type statement_expression -%type argument -%type object_creation_expression -%type equality_expression -%type relational_expression -%type and_expression -%type inclusive_or_expression -%type conditional_and_expression -%type conditional_or_expression -%type post_increment_expression -%type post_decrement_expression -%type struct_or_array_initializer -%type block -%type statement -%type declaration_statement -%type embedded_statement -%type expression_statement -%type selection_statement -%type if_statement -%type iteration_statement -%type while_statement -%type for_statement -%type foreach_statement -%type jump_statement -%type return_statement -%type fixed_parameter -%type variable_declaration -%type variable_declarator -%type field_declaration -%type property_declaration -%type accessor_declarations -%type get_accessor_declaration -%type set_accessor_declaration -%type accessor_body -%type named_argument -%type constant_declaration -%type struct_declaration -%type method_declaration -%type method_header -%type enum_declaration -%type flags_declaration -%type opt_enum_member_declarations -%type enum_member_declarations -%type enum_body -%type enum_member_declaration -%type opt_flags_member_declarations -%type flags_member_declarations -%type flags_body -%type flags_member_declaration -%type opt_attribute_sections -%type attribute_sections -%type attribute_section -%type attribute_list -%type attribute_arguments -%type attribute - -%% - -compilation_unit - : /* empty */ - | opt_using_directives outer_declarations - ; - -opt_using_directives - : /* empty */ - | using_directives - ; - -using_directives - : using_directive - | using_directives using_directive - ; - -using_directive - : USING IDENTIFIER SEMICOLON - { - current_source_file->using_directives = g_list_append (current_source_file->using_directives, $2); - } - ; - -outer_declarations - : outer_declaration - | outer_declarations outer_declaration - ; - -outer_declaration - : namespace_declaration - | type_declaration - ; - -namespace_declaration - : opt_attribute_sections NAMESPACE IDENTIFIER - { - current_namespace = g_new0 (ValaNamespace, 1); - current_namespace->name = $3; - current_namespace->cprefix = current_namespace->name; - current_namespace->source_file = current_source_file; - current_namespace->lower_case_cname = camel_case_to_lower_case (current_namespace->name); - /* we know that this is safe */ - current_namespace->lower_case_cname[strlen (current_namespace->lower_case_cname)] = '_'; - - current_namespace->upper_case_cname = camel_case_to_upper_case (current_namespace->name); - /* we know that this is safe */ - current_namespace->upper_case_cname[strlen (current_namespace->upper_case_cname)] = '_'; - - current_namespace->annotations = $1; - - GList *l, *al; - for (l = current_namespace->annotations; l != NULL; l = l->next) { - ValaAnnotation *anno = l->data; - - if (strcmp (anno->type->type_name, "CCode") == 0) { - for (al = anno->argument_list; al != NULL; al = al->next) { - ValaNamedArgument *arg = al->data; - - if (strcmp (arg->name, "lower_case_cprefix") == 0) { - current_namespace->lower_case_cname = g_strdup (eval_string (arg->expression->str)); - current_namespace->upper_case_cname = g_ascii_strup (current_namespace->lower_case_cname, -1); - } else if (strcmp (arg->name, "cprefix") == 0) { - current_namespace->cprefix = eval_string (arg->expression->str); - } else if (strcmp (arg->name, "include_filename") == 0) { - current_namespace->include_filename = eval_string (arg->expression->str); - } - } - } else if (strcmp (anno->type->type_name, "Import") == 0) { - current_namespace->import = TRUE; - } - } - - current_source_file->namespaces = g_list_append (current_source_file->namespaces, current_namespace); - } - namespace_body - { - current_namespace = current_source_file->root_namespace; - } - ; - -namespace_body - : OPEN_BRACE opt_namespace_member_declarations CLOSE_BRACE - ; - -opt_namespace_member_declarations - : /* empty */ - | namespace_member_declarations - ; - -namespace_member_declarations - : namespace_member_declaration - | namespace_member_declarations namespace_member_declaration - ; - -namespace_member_declaration - : type_declaration - | field_declaration - { - current_namespace->fields = g_list_append (current_namespace->fields, $1); - $1->namespace = current_namespace; - } - | method_declaration - { - current_namespace->methods = g_list_append (current_namespace->methods, $1); - } - ; - -type_declaration - : class_declaration - | struct_declaration - | enum_declaration - { - $1->namespace = current_namespace; - current_namespace->enums = g_list_append (current_namespace->enums, $1); - } - | flags_declaration - { - $1->namespace = current_namespace; - current_namespace->flags_list = g_list_append (current_namespace->flags_list, $1); - } - ; - -class_declaration - : opt_attribute_sections opt_modifiers CLASS IDENTIFIER opt_type_parameter_list opt_class_base - { - current_class = g_new0 (ValaClass, 1); - current_class->name = g_strdup ($4); - current_class->base_types = $6; - current_class->type_parameters = $5; - current_class->location = current_location (@3); - current_class->namespace = current_namespace; - current_class->cname = g_strdup_printf ("%s%s", current_namespace->cprefix, current_class->name); - current_class->lower_case_cname = camel_case_to_lower_case (current_class->name); - current_class->upper_case_cname = camel_case_to_upper_case (current_class->name); - current_namespace->classes = g_list_append (current_namespace->classes, current_class); - } - class_body - ; - -opt_type_parameter_list - : /* empty */ - { - $$ = NULL; - } - | type_parameter_list - { - $$ = $1; - } - ; - -type_parameter_list - : OP_LT type_parameters OP_GT - { - $$ = $2; - } - ; - -type_parameters - : IDENTIFIER - { - $$ = g_list_append (NULL, $1); - } - | type_parameters COMMA IDENTIFIER - { - $$ = g_list_append ($1, $3); - } - ; - -opt_class_base - : /* empty */ - { - $$ = NULL; - } - | class_base - { - $$ = $1; - } - ; - -class_base - : COLON type_list - { - $$ = $2; - } - ; - -type_list - : type_name - { - $$ = g_list_append (NULL, $1); - } - | type_list COMMA type_name - { - $$ = g_list_append ($1, $3); - } - ; - -type_name - : IDENTIFIER opt_type_argument_list opt_at opt_brackets - { - ValaTypeReference *type_reference = g_new0 (ValaTypeReference, 1); - type_reference->type_name = g_strdup ($1); - type_reference->location = current_location (@1); - type_reference->own = $3; - type_reference->array_type = $4; - type_reference->type_params = $2; - $$ = type_reference; - } - | IDENTIFIER DOT IDENTIFIER opt_type_argument_list opt_at opt_brackets - { - ValaTypeReference *type_reference = g_new0 (ValaTypeReference, 1); - type_reference->namespace_name = g_strdup ($1); - type_reference->type_name = g_strdup ($3); - type_reference->location = current_location (@1); - type_reference->own = $5; - type_reference->array_type = $6; - type_reference->type_params = $4; - $$ = type_reference; - } - ; - -opt_type_argument_list - : /* empty */ - { - $$ = NULL; - } - | type_argument_list - { - $$ = $1; - } - ; - -type_argument_list - : OP_LT type_arguments OP_GT - { - $$ = $2; - } - ; - -type_arguments - : opt_parameter_modifier type_name - { - $$ = g_list_append (NULL, $2);; - } - | type_arguments COMMA opt_parameter_modifier type_name - { - $$ = g_list_append ($1, $4);; - } - ; - -opt_at - : /* empty */ - { - $$ = FALSE; - } - | HASH - { - $$ = TRUE; - } - ; - -opt_brackets - : /* empty */ - { - $$ = FALSE; - } - | OPEN_BRACKET CLOSE_BRACKET - { - $$ = TRUE; - } - ; - -class_body - : OPEN_BRACE opt_class_member_declarations CLOSE_BRACE - ; - -opt_class_member_declarations - : /* empty */ - | class_member_declarations - ; - -class_member_declarations - : class_member_declaration - | class_member_declarations class_member_declaration - ; - -class_member_declaration - : constant_declaration - { - $1->class = current_class; - current_class->constants = g_list_append (current_class->constants, $1); - } - | method_declaration - { - $1->class = current_class; - if ($1->cname == NULL) { - $1->cname = g_strdup_printf ("%s%s_%s", current_namespace->lower_case_cname, current_class->lower_case_cname, $1->name); - } - current_class->methods = g_list_append (current_class->methods, current_method); - } - | field_declaration - { - $1->class = current_class; - current_class->fields = g_list_append (current_class->fields, $1); - } - | property_declaration - { - $1->class = current_class; - current_class->properties = g_list_append (current_class->properties, $1); - } - ; - -constant_declaration - : opt_attribute_sections opt_modifiers CONST declaration_statement - { - $$ = g_new0 (ValaConstant, 1); - $$->location = current_location (@3); - /* default constants to private access */ - if (($2 & VALA_MODIFIER_PUBLIC) == 0) { - $$->modifiers = $2 | VALA_MODIFIER_PRIVATE; - } else { - $$->modifiers = $2; - } - $$->declaration_statement = $4; - } - ; - -method_declaration - : method_header method_body - { - $$ = $1; - } - ; - -method_header - : opt_attribute_sections opt_modifiers opt_parameter_modifier type_name IDENTIFIER OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS - { - $$ = g_new0 (ValaMethod, 1); - $$->name = g_strdup ($5); - $$->return_type = $4; - $$->formal_parameters = $7; - $$->modifiers = $2; - $$->location = current_location (@5); - - $$->annotations = $1; - - GList *l, *al; - for (l = $$->annotations; l != NULL; l = l->next) { - ValaAnnotation *anno = l->data; - - if (strcmp (anno->type->type_name, "CCode") == 0) { - for (al = anno->argument_list; al != NULL; al = al->next) { - ValaNamedArgument *arg = al->data; - - if (strcmp (arg->name, "cname") == 0) { - $$->cname = eval_string (arg->expression->str); - } - } - } else if (strcmp (anno->type->type_name, "ReturnsModifiedPointer") == 0) { - $$->returns_modified_pointer = TRUE; - } else if (strcmp (anno->type->type_name, "InstanceLast") == 0) { - $$->instance_last = TRUE; - } - } - - current_method = $$; - } - ; - -opt_formal_parameter_list - : /* empty */ - { - $$ = NULL; - } - | formal_parameter_list - { - $$ = $1; - } - ; - -formal_parameter_list - : fixed_parameters - ; - -fixed_parameters - : fixed_parameter - { - $$ = g_list_append (NULL, $1); - } - | fixed_parameters COMMA fixed_parameter - { - $$ = g_list_append ($1, $3); - } - ; - -fixed_parameter - : opt_parameter_modifier type_name IDENTIFIER - { - $$ = g_new0 (ValaFormalParameter, 1); - $$->type = $2; - $$->name = $3; - $$->modifier = $1; - $$->location = current_location (@1); - } - ; - -opt_parameter_modifier - : /* empty */ - { - $$ = 0; - } - | parameter_modifier - { - $$ = $1; - } - ; - -parameter_modifier - : REF - { - $$ = 1; - } - | WEAK - { - $$ = 0; - } - | OUT - { - $$ = 2; - } - ; - -method_body - : block - { - current_method->body = $1; - } - | SEMICOLON - ; - -field_declaration - : opt_attribute_sections opt_modifiers declaration_statement - { - $$ = g_new0 (ValaField, 1); - $$->location = current_location (@3); - /* default fields to private access */ - if (($2 & VALA_MODIFIER_PUBLIC) == 0) { - $$->modifiers = $2 | VALA_MODIFIER_PRIVATE; - } else { - $$->modifiers = $2; - } - $$->declaration_statement = $3; - - $$->annotations = $1; - - GList *l, *al; - for (l = $$->annotations; l != NULL; l = l->next) { - ValaAnnotation *anno = l->data; - - if (strcmp (anno->type->type_name, "CCode") == 0) { - for (al = anno->argument_list; al != NULL; al = al->next) { - ValaNamedArgument *arg = al->data; - - if (strcmp (arg->name, "cname") == 0) { - $$->cname = eval_string (arg->expression->str); - } - } - } - } - - /* readonly => create private field and public construct-only property */ - if ($2 & VALA_MODIFIER_READONLY) { - /* error if not in class or not public */ - $$->modifiers = VALA_MODIFIER_PRIVATE; - char *name = $$->declaration_statement->variable_declaration->declarator->name; - $$->declaration_statement->variable_declaration->declarator->name = g_strdup_printf ("_%s", name); - - ValaProperty *prop = g_new0 (ValaProperty, 1); -; - prop->name = name; - prop->location = current_location (@3); - prop->return_type = $$->declaration_statement->variable_declaration->type; - prop->modifiers = VALA_MODIFIER_PUBLIC; - prop->class = current_class; - - ValaStatement *stmt; - - prop->get_statement = g_new0 (ValaStatement, 1); - prop->get_statement->type = VALA_STATEMENT_TYPE_BLOCK; - prop->get_statement->location = current_location (@3); - - stmt = g_new0 (ValaStatement, 1); - stmt->type = VALA_STATEMENT_TYPE_RETURN; - stmt->location = current_location (@3); - stmt->expr = g_new0 (ValaExpression, 1); - stmt->expr->type = VALA_EXPRESSION_TYPE_SIMPLE_NAME; - stmt->expr->location = current_location (@3); - stmt->expr->str = g_strdup_printf ("_%s", name); - prop->get_statement->block.statements = g_list_append (prop->get_statement->block.statements, stmt); - - prop->set_statement = g_new0 (ValaStatement, 1); - prop->set_statement->type = VALA_STATEMENT_TYPE_BLOCK; - prop->set_statement->location = current_location (@3); - - stmt = g_new0 (ValaStatement, 1); - stmt->type = VALA_STATEMENT_TYPE_EXPRESSION; - stmt->location = current_location (@3); - stmt->expr = g_new0 (ValaExpression, 1); - stmt->expr->type = VALA_EXPRESSION_TYPE_ASSIGNMENT; - stmt->expr->location = current_location (@1); - stmt->expr->assignment.left = g_new0 (ValaExpression, 1); - stmt->expr->assignment.left->type = VALA_EXPRESSION_TYPE_SIMPLE_NAME; - stmt->expr->assignment.left->location = current_location (@3); - stmt->expr->assignment.left->str = g_strdup_printf ("_%s", name); - stmt->expr->assignment.right = g_new0 (ValaExpression, 1); - stmt->expr->assignment.right->type = VALA_EXPRESSION_TYPE_SIMPLE_NAME; - stmt->expr->assignment.right->location = current_location (@3); - stmt->expr->assignment.right->str = "value"; - prop->set_statement->block.statements = g_list_append (prop->set_statement->block.statements, stmt); - - current_class->properties = g_list_append (current_class->properties, prop); - } - } - ; - -opt_modifiers - : /* emtpty */ - { - $$ = 0; - } - | modifiers - { - $$ = $1; - } - ; - -modifiers - : modifier - { - $$ = $1; - } - | modifiers modifier - { - $$ = $1 | $2; - } - ; - -modifier - : PUBLIC - { - $$ = VALA_MODIFIER_PUBLIC; - } - | PRIVATE - { - $$ = VALA_MODIFIER_PRIVATE; - } - | STATIC - { - $$ = VALA_MODIFIER_STATIC; - } - | ABSTRACT - { - $$ = VALA_MODIFIER_ABSTRACT; - } - | VIRTUAL - { - $$ = VALA_MODIFIER_VIRTUAL; - } - | OVERRIDE - { - $$ = VALA_MODIFIER_OVERRIDE; - } - | READONLY - { - $$ = VALA_MODIFIER_READONLY; - } - ; - -property_declaration - : opt_attribute_sections opt_modifiers opt_parameter_modifier type_name IDENTIFIER OPEN_BRACE accessor_declarations CLOSE_BRACE - { - $$ = $7; - $$->name = g_strdup ($5); - $$->location = current_location (@5); - $$->return_type = $4; - /* default fields to private access */ - if (($2 & VALA_MODIFIER_PUBLIC) == 0) { - yyerror (&@2, "Properties must have a public modifier."); - YYERROR; - } - $$->modifiers = $2; - - if ($$->get_statement == NULL && $$->set_statement == NULL) { - // no property bodies provided => create private field and public construct-only property - - ValaField *f = g_new0 (ValaField, 1); - - f->location = current_location (@5); - f->modifiers = VALA_MODIFIER_PRIVATE; - f->declaration_statement = g_new0 (ValaStatement, 1); - f->declaration_statement->type = VALA_STATEMENT_TYPE_VARIABLE_DECLARATION; - f->declaration_statement->location = current_location (@5); - f->declaration_statement->variable_declaration = g_new0 (ValaVariableDeclaration, 1); - f->declaration_statement->variable_declaration->type = $4; - f->declaration_statement->variable_declaration->declarator = g_new0 (ValaVariableDeclarator, 1); - f->declaration_statement->variable_declaration->declarator->name = g_strdup_printf ("_%s", $5); - f->declaration_statement->variable_declaration->declarator->location = current_location (@5); - f->class = current_class; - - ValaStatement *stmt; - - $$->get_statement = g_new0 (ValaStatement, 1); - $$->get_statement->type = VALA_STATEMENT_TYPE_BLOCK; - $$->get_statement->location = current_location (@5); - - stmt = g_new0 (ValaStatement, 1); - stmt->type = VALA_STATEMENT_TYPE_RETURN; - stmt->location = current_location (@5); - stmt->expr = g_new0 (ValaExpression, 1); - stmt->expr->type = VALA_EXPRESSION_TYPE_SIMPLE_NAME; - stmt->expr->location = current_location (@5); - stmt->expr->str = g_strdup_printf ("_%s", $5); - $$->get_statement->block.statements = g_list_append ($$->get_statement->block.statements, stmt); - - $$->set_statement = g_new0 (ValaStatement, 1); - $$->set_statement->type = VALA_STATEMENT_TYPE_BLOCK; - $$->set_statement->location = current_location (@5); - - stmt = g_new0 (ValaStatement, 1); - stmt->type = VALA_STATEMENT_TYPE_EXPRESSION; - stmt->location = current_location (@5); - stmt->expr = g_new0 (ValaExpression, 1); - stmt->expr->type = VALA_EXPRESSION_TYPE_ASSIGNMENT; - stmt->expr->location = current_location (@5); - stmt->expr->assignment.left = g_new0 (ValaExpression, 1); - stmt->expr->assignment.left->type = VALA_EXPRESSION_TYPE_SIMPLE_NAME; - stmt->expr->assignment.left->location = current_location (@5); - stmt->expr->assignment.left->str = g_strdup_printf ("_%s", $5); - stmt->expr->assignment.right = g_new0 (ValaExpression, 1); - stmt->expr->assignment.right->type = VALA_EXPRESSION_TYPE_SIMPLE_NAME; - stmt->expr->assignment.right->location = current_location (@5); - stmt->expr->assignment.right->str = "value"; - $$->set_statement->block.statements = g_list_append ($$->set_statement->block.statements, stmt); - - current_class->fields = g_list_append (current_class->fields, f); - } - } - ; - -accessor_declarations - : get_accessor_declaration - { - $$ = g_new0 (ValaProperty, 1); - $$->get_statement = $1; - } - | set_accessor_declaration - { - $$ = g_new0 (ValaProperty, 1); - $$->set_statement = $1; - } - | get_accessor_declaration set_accessor_declaration - { - $$ = g_new0 (ValaProperty, 1); - $$->get_statement = $1; - $$->set_statement = $2; - } - | set_accessor_declaration get_accessor_declaration { - $$ = g_new0 (ValaProperty, 1); - $$->get_statement = $1; - $$->set_statement = $2; - } - - ; - -get_accessor_declaration - : GET accessor_body - { - $$ = $2; - } - ; - -set_accessor_declaration - : SET accessor_body - { - $$ = $2; - } - | CONSTRUCT accessor_body - { - $$ = $2; - } - | SET CONSTRUCT accessor_body - { - $$ = $3; - } - ; - -accessor_body - : block - | SEMICOLON - { - $$ = NULL; - } - ; - -block - : OPEN_BRACE opt_statement_list CLOSE_BRACE - { - $$ = g_new0 (ValaStatement, 1); - $$->type = VALA_STATEMENT_TYPE_BLOCK; - $$->location = current_location (@1); - $$->block.statements = $2; - } - ; - -opt_statement_list - : /* empty */ - { - $$ = NULL; - } - | statement_list - { - $$ = $1; - } - ; - -statement_list - : statement - { - $$ = g_list_append (NULL, $1); - } - | statement_list statement - { - $$ = g_list_append ($1, $2); - } - ; - -statement - : declaration_statement - { - $$ = $1; - } - | embedded_statement - { - $$ = $1; - } - ; - -declaration_statement - : variable_declaration SEMICOLON - { - $$ = g_new0 (ValaStatement, 1); - $$->type = VALA_STATEMENT_TYPE_VARIABLE_DECLARATION; - $$->location = current_location (@1); - $$->variable_declaration = $1; - } - ; - -variable_declaration - : opt_parameter_modifier type_name variable_declarator - { - $$ = g_new0 (ValaVariableDeclaration, 1); - $$->type = $2; - $$->declarator = $3; - } - | - VAR IDENTIFIER ASSIGN variable_initializer - { - $$ = g_new0 (ValaVariableDeclaration, 1); - $$->type = g_new0 (ValaTypeReference, 1); - $$->type->location = current_location (@1); - $$->declarator = g_new0 (ValaVariableDeclarator, 1); - $$->declarator->name = $2; - $$->declarator->initializer = $4; - $$->declarator->location = current_location (@1); - } - ; - -variable_declarator - : IDENTIFIER - { - $$ = g_new0 (ValaVariableDeclarator, 1); - $$->name = $1; - $$->location = current_location (@1); - } - | IDENTIFIER ASSIGN variable_initializer - { - $$ = g_new0 (ValaVariableDeclarator, 1); - $$->name = $1; - $$->initializer = $3; - $$->location = current_location (@1); - } - ; - -opt_variable_initializer_list - : /* empty */ - { - $$ = NULL; - } - | variable_initializer_list - { - $$ = $1; - } - ; - -variable_initializer_list - : variable_initializer - { - $$ = g_list_append (NULL, $1); - } - | variable_initializer_list COMMA variable_initializer - { - $$ = g_list_append ($1, $3); - } - ; - -variable_initializer - : argument - { - $$ = $1; - } - | struct_or_array_initializer - { - $$ = $1; - } - ; - -opt_expression - : /* empty */ - { - $$ = NULL; - } - | expression - ; - -expression - : conditional_or_expression - | assignment - ; - -equality_expression - : relational_expression - | equality_expression OP_EQ relational_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OPERATION; - $$->location = current_location (@1); - $$->op.left = $1; - $$->op.type = VALA_OP_TYPE_EQ; - $$->op.right = $3; - } - | equality_expression OP_NE relational_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OPERATION; - $$->location = current_location (@1); - $$->op.left = $1; - $$->op.type = VALA_OP_TYPE_NE; - $$->op.right = $3; - } - ; - -and_expression - : equality_expression - | and_expression BITWISE_AND equality_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OPERATION; - $$->location = current_location (@1); - $$->op.left = $1; - $$->op.type = VALA_OP_TYPE_BITWISE_AND; - $$->op.right = $3; - } - ; - -inclusive_or_expression - : and_expression - | inclusive_or_expression BITWISE_OR and_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OPERATION; - $$->location = current_location (@1); - $$->op.left = $1; - $$->op.type = VALA_OP_TYPE_BITWISE_OR; - $$->op.right = $3; - } - ; - -conditional_and_expression - : inclusive_or_expression - | conditional_and_expression OP_AND inclusive_or_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OPERATION; - $$->location = current_location (@1); - $$->op.left = $1; - $$->op.type = VALA_OP_TYPE_AND; - $$->op.right = $3; - } - ; - -conditional_or_expression - : conditional_and_expression - | conditional_or_expression OP_OR conditional_and_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OPERATION; - $$->location = current_location (@1); - $$->op.left = $1; - $$->op.type = VALA_OP_TYPE_OR; - $$->op.right = $3; - } - ; - -relational_expression - : additive_expression - { - $$ = $1; - } - | relational_expression OP_LT additive_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OPERATION; - $$->location = current_location (@1); - $$->op.left = $1; - $$->op.type = VALA_OP_TYPE_LT; - $$->op.right = $3; - } - | relational_expression OP_GT additive_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OPERATION; - $$->location = current_location (@1); - $$->op.left = $1; - $$->op.type = VALA_OP_TYPE_GT; - $$->op.right = $3; - } - | relational_expression OP_LE additive_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OPERATION; - $$->location = current_location (@1); - $$->op.left = $1; - $$->op.type = VALA_OP_TYPE_LE; - $$->op.right = $3; - } - | relational_expression OP_GE additive_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OPERATION; - $$->location = current_location (@1); - $$->op.left = $1; - $$->op.type = VALA_OP_TYPE_GE; - $$->op.right = $3; - } - | relational_expression IS type_name - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_IS; - $$->location = current_location (@1); - $$->is.expr = $1; - $$->is.type = $3; - } - ; - -additive_expression - : multiplicative_expression - { - $$ = $1; - } - | additive_expression PLUS multiplicative_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OPERATION; - $$->location = current_location (@1); - $$->op.left = $1; - $$->op.type = VALA_OP_TYPE_PLUS; - $$->op.right = $3; - } - | additive_expression MINUS multiplicative_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OPERATION; - $$->location = current_location (@1); - $$->op.left = $1; - $$->op.type = VALA_OP_TYPE_MINUS; - $$->op.right = $3; - } - ; - -multiplicative_expression - : unary_expression - { - $$ = $1; - } - | multiplicative_expression STAR unary_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OPERATION; - $$->location = current_location (@1); - $$->op.left = $1; - $$->op.type = VALA_OP_TYPE_MUL; - $$->op.right = $3; - } - | multiplicative_expression DIV unary_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OPERATION; - $$->location = current_location (@1); - $$->op.left = $1; - $$->op.type = VALA_OP_TYPE_DIV; - $$->op.right = $3; - } - ; - -unary_expression - : primary_expression - { - $$ = $1; - } - | MINUS unary_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OPERATION; - $$->location = current_location (@1); - $$->op.type = VALA_OP_TYPE_MINUS; - $$->op.right = $2; - } - | OP_NEG unary_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OPERATION; - $$->location = current_location (@1); - $$->op.type = VALA_OP_TYPE_NEG; - $$->op.right = $2; - } - | cast_expression - ; - -cast_expression - : OPEN_CAST_PARENS type_name CLOSE_PARENS unary_expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_CAST; - $$->location = current_location (@1); - $$->cast.type = $2; - $$->cast.inner = $4; - } - ; - -primary_expression - : literal - { - $$ = $1; - } - | simple_name - { - $$ = $1; - } - | parenthesized_expression - { - $$ = $1; - } - | member_access - { - $$ = $1; - } - | invocation_expression - { - $$ = $1; - } - | element_access - { - $$ = $1; - } - | this_access - { - $$ = $1; - } - | post_increment_expression - { - $$ = $1; - } - | post_decrement_expression - { - $$ = $1; - } - | object_creation_expression - { - $$ = $1; - } - ; - -literal - : LITERAL_CHARACTER - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_LITERAL_CHARACTER; - $$->location = current_location (@1); - $$->str = $1; - } - | LITERAL_INTEGER - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_LITERAL_INTEGER; - $$->location = current_location (@1); - $$->str = $1; - } - | LITERAL_STRING - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_LITERAL_STRING; - $$->location = current_location (@1); - $$->str = $1; - } - | boolean_literal - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_LITERAL_BOOLEAN; - $$->location = current_location (@1); - $$->num = $1; - } - | VALA_NULL - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_LITERAL_NULL; - $$->location = current_location (@1); - } - ; - -boolean_literal - : VALA_TRUE - { - $$ = TRUE; - } - | VALA_FALSE - { - $$ = FALSE; - } - ; - -simple_name - : IDENTIFIER - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_SIMPLE_NAME; - $$->location = current_location (@1); - $$->str = $1; - } - ; - -parenthesized_expression - : OPEN_PARENS expression CLOSE_PARENS - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_PARENTHESIZED; - $$->location = current_location (@1); - $$->inner = $2; - } - ; - -member_access - : primary_expression DOT IDENTIFIER - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_MEMBER_ACCESS; - $$->location = current_location (@1); - $$->member_access.left = $1; - $$->member_access.right = $3; - } - ; - -invocation_expression - : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_INVOCATION; - $$->location = current_location (@1); - $$->invocation.call = $1; - $$->invocation.argument_list = $3; - } - ; - -opt_argument_list - : /* empty */ - { - $$ = NULL; - } - | argument_list - { - $$ = $1; - } - ; - -argument_list - : argument - { - $$ = g_list_append (NULL, $1); - } - | argument_list COMMA argument - { - $$ = g_list_append ($1, $3); - } - ; - -argument - : expression - { - $$ = $1; - } - | REF expression - { - $$ = $2; - $$->ref_variable = TRUE; - } - | OUT expression - { - $$ = $2; - $$->out_variable = TRUE; - } - ; - -element_access - : primary_expression OPEN_BRACKET primary_expression CLOSE_BRACKET - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_ELEMENT_ACCESS; - $$->location = current_location (@1); - $$->element_access.array = $1; - $$->element_access.index = $3; - } - ; - -this_access - : THIS - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_THIS_ACCESS; - $$->location = current_location (@1); - } - ; - -post_increment_expression - : primary_expression OP_INC - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_POSTFIX; - $$->location = current_location (@1); - $$->postfix.inner = $1; - $$->postfix.cop = "++"; - } - ; - -post_decrement_expression - : primary_expression OP_DEC - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_POSTFIX; - $$->location = current_location (@1); - $$->postfix.inner = $1; - $$->postfix.cop = "--"; - } - ; - -object_creation_expression - : IDENTIFIER type_name OPEN_PARENS opt_named_argument_list CLOSE_PARENS - { - if (strcmp ($1, "new") != 0) { - /* raise error */ - fprintf (stderr, "syntax error: object creation expression without new\n"); - } - - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_OBJECT_CREATION; - $$->location = current_location (@1); - $$->object_creation.type = $2; - $$->object_creation.named_argument_list = $4; - } - ; - -opt_named_argument_list - : /* empty */ - { - $$ = NULL; - } - | named_argument_list - { - $$ = $1; - } - ; - -named_argument_list - : named_argument - { - $$ = g_list_append (NULL, $1); - } - | named_argument_list COMMA named_argument - { - $$ = g_list_append ($1, $3); - } - ; - -named_argument - : IDENTIFIER ASSIGN expression - { - $$ = g_new0 (ValaNamedArgument, 1); - $$->name = $1; - $$->expression = $3; - $$->location = current_location (@1); - } - ; - -embedded_statement - : block - { - $$ = $1; - } - | empty_statement - { - $$ = NULL; - } - | expression_statement - { - $$ = $1; - } - | selection_statement - { - $$ = $1; - } - | iteration_statement - { - $$ = $1; - } - | jump_statement - { - $$ = $1; - } - ; - -empty_statement - : SEMICOLON - ; - -expression_statement - : statement_expression SEMICOLON - { - $$ = g_new0 (ValaStatement, 1); - $$->type = VALA_STATEMENT_TYPE_EXPRESSION; - $$->location = current_location (@1); - $$->expr = $1; - } - ; - -statement_expression - : invocation_expression - { - $$ = $1; - } - | object_creation_expression - { - $$ = $1; - } - | assignment - { - $$ = $1; - } - | post_increment_expression - { - $$ = $1; - } - | post_decrement_expression - { - $$ = $1; - } - ; - -assignment - : primary_expression assignment_operator expression - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_ASSIGNMENT; - $$->location = current_location (@1); - $$->assignment.left = $1; - $$->assignment.right = $3; - } - ; - -assignment_operator - : ASSIGN - | ASSIGN_BITWISE_OR - ; - -selection_statement - : if_statement - { - $$ = $1; - } - ; - -if_statement - : IF OPEN_PARENS expression CLOSE_PARENS embedded_statement - { - $$ = g_new0 (ValaStatement, 1); - $$->type = VALA_STATEMENT_TYPE_IF; - $$->location = current_location (@1); - $$->if_stmt.condition = $3; - $$->if_stmt.true_stmt = $5; - } - | IF OPEN_PARENS expression CLOSE_PARENS embedded_statement ELSE embedded_statement - { - $$ = g_new0 (ValaStatement, 1); - $$->type = VALA_STATEMENT_TYPE_IF; - $$->location = current_location (@1); - $$->if_stmt.condition = $3; - $$->if_stmt.true_stmt = $5; - $$->if_stmt.false_stmt = $7; - } - ; - - -iteration_statement - : while_statement - | for_statement - { - $$ = $1; - } - | foreach_statement - { - $$ = $1; - } - ; - -while_statement - : WHILE OPEN_PARENS expression CLOSE_PARENS embedded_statement - { - $$ = g_new0 (ValaStatement, 1); - $$->type = VALA_STATEMENT_TYPE_WHILE; - $$->location = current_location (@1); - $$->while_stmt.condition = $3; - $$->while_stmt.loop = $5; - } - ; - -for_statement - : FOR OPEN_PARENS opt_statement_expression_list SEMICOLON opt_expression SEMICOLON opt_statement_expression_list CLOSE_PARENS embedded_statement - { - $$ = g_new0 (ValaStatement, 1); - $$->type = VALA_STATEMENT_TYPE_FOR; - $$->location = current_location (@1); - $$->for_stmt.initializer = $3; - $$->for_stmt.condition = $5; - $$->for_stmt.iterator = $7; - $$->for_stmt.loop = $9; - } - ; - -opt_statement_expression_list - : /* empty */ - { - $$ = NULL; - } - | statement_expression_list - { - $$ = $1; - } - ; - -statement_expression_list - : statement_expression - { - $$ = g_list_append (NULL, $1); - } - | statement_expression_list COMMA statement_expression - { - $$ = g_list_append ($1, $3); - } - ; - -foreach_statement - : FOREACH OPEN_PARENS type_name IDENTIFIER IN expression CLOSE_PARENS embedded_statement - { - $$ = g_new0 (ValaStatement, 1); - $$->type = VALA_STATEMENT_TYPE_FOREACH; - $$->location = current_location (@1); - $$->foreach_stmt.type = $3; - $$->foreach_stmt.name = $4; - $$->foreach_stmt.container = $6; - $$->foreach_stmt.loop = $8; - } - ; - -jump_statement - : return_statement - { - $$ = $1; - } - ; - -return_statement - : RETURN opt_expression SEMICOLON - { - $$ = g_new0 (ValaStatement, 1); - $$->type = VALA_STATEMENT_TYPE_RETURN; - $$->location = current_location (@1); - $$->expr = $2; - } - ; - -struct_or_array_initializer - : OPEN_BRACE opt_variable_initializer_list CLOSE_BRACE - { - $$ = g_new0 (ValaExpression, 1); - $$->type = VALA_EXPRESSION_TYPE_STRUCT_OR_ARRAY_INITIALIZER; - $$->location = current_location (@1); - $$->list = $2; - } - ; - -struct_declaration - : opt_attribute_sections opt_modifiers STRUCT IDENTIFIER opt_type_parameter_list - { - $$ = g_new0 (ValaStruct, 1); - $$->name = g_strdup ($4); - $$->location = current_location (@3); - $$->type_parameters = $5; - $$->namespace = current_namespace; - $$->cname = g_strdup_printf ("%s%s", current_namespace->cprefix, $$->name); - $$->lower_case_cname = camel_case_to_lower_case ($$->name); - $$->upper_case_cname = camel_case_to_upper_case ($$->name); - current_namespace->structs = g_list_append (current_namespace->structs, $$); - current_struct = $$; - - $$->annotations = $1; - - GList *l, *al; - for (l = $$->annotations; l != NULL; l = l->next) { - ValaAnnotation *anno = l->data; - - if (strcmp (anno->type->type_name, "CCode") == 0) { - for (al = anno->argument_list; al != NULL; al = al->next) { - ValaNamedArgument *arg = al->data; - - if (strcmp (arg->name, "cname") == 0) { - $$->cname = eval_string (arg->expression->str); - } - } - } else if (strcmp (anno->type->type_name, "ReferenceType") == 0) { - $$->reference_type = TRUE; - } - } - } - struct_body - { - current_struct = NULL; - } - ; - -struct_body - : OPEN_BRACE opt_struct_member_declarations CLOSE_BRACE - ; - -opt_struct_member_declarations - : /* empty */ - | struct_member_declarations - ; - -struct_member_declarations - : struct_member_declaration - | struct_member_declarations struct_member_declaration - ; - -struct_member_declaration - : field_declaration - { - $1->is_struct_field = TRUE; - $1->struct_ = current_struct; - current_struct->fields = g_list_append (current_struct->fields, $1); - } - | method_declaration - { - $1->is_struct_method = TRUE; - $1->struct_ = current_struct; - current_struct->methods = g_list_append (current_struct->methods, $1); - } - ; - -enum_declaration - : opt_attribute_sections opt_modifiers ENUM IDENTIFIER enum_body - { - GList *l; - - $$ = g_new0 (ValaEnum, 1); - $$->name = $4; - $$->location = current_location (@3); - $$->cname = g_strdup_printf ("%s%s", current_namespace->cprefix, $$->name); - $$->upper_case_cname = camel_case_to_upper_case ($$->name); - $$->values = $5; - - for (l = $$->values; l != NULL; l = l->next) { - ValaEnumValue *value = l->data; - value->cname = g_strdup_printf ("%s%s_%s", current_namespace->upper_case_cname, $$->upper_case_cname, value->name); - } - } - ; - -enum_body - : OPEN_BRACE opt_enum_member_declarations CLOSE_BRACE - { - $$ = $2; - } - ; - -opt_enum_member_declarations - : /* empty */ - { - $$ = NULL; - } - | enum_member_declarations - { - $$ = $1; - } - ; - -enum_member_declarations - : enum_member_declaration - { - $$ = g_list_append (NULL, $1); - } - | enum_member_declarations COMMA enum_member_declaration - { - $$ = g_list_append ($1, $3); - } - ; - -enum_member_declaration - : IDENTIFIER - { - $$ = g_new0 (ValaEnumValue, 1); - $$->name = $1; - } - | IDENTIFIER ASSIGN expression - { - $$ = g_new0 (ValaEnumValue, 1); - $$->name = $1; - } - ; - -flags_declaration - : opt_attribute_sections opt_modifiers FLAGS IDENTIFIER flags_body - { - $$ = g_new0 (ValaFlags, 1); - $$->name = $4; - $$->location = current_location (@3); - $$->cname = g_strdup_printf ("%s%s", current_namespace->cprefix, $$->name); - $$->values = $5; - } - ; - -flags_body - : OPEN_BRACE opt_flags_member_declarations CLOSE_BRACE - { - $$ = $2; - } - ; - -opt_flags_member_declarations - : /* empty */ - { - $$ = NULL; - } - | flags_member_declarations - { - $$ = $1; - } - ; - -flags_member_declarations - : flags_member_declaration - { - $$ = g_list_append (NULL, $1); - } - | flags_member_declarations COMMA flags_member_declaration - { - $$ = g_list_append ($1, $3); - } - ; - -flags_member_declaration - : IDENTIFIER - { - $$ = g_new0 (ValaFlagsValue, 1); - $$->name = $1; - } - | IDENTIFIER ASSIGN expression - { - $$ = g_new0 (ValaFlagsValue, 1); - $$->name = $1; - } - ; - -opt_attribute_sections - : /* empty */ - { - $$ = NULL; - } - | attribute_sections - { - $$ = $1; - } - ; - -attribute_sections - : attribute_section - { - $$ = $1; - } - | attribute_sections attribute_section - { - $$ = g_list_concat ($1, $2); - } - ; - -attribute_section - : OPEN_BRACKET attribute_list CLOSE_BRACKET - { - $$ = $2; - } - ; - -attribute_list - : attribute - { - $$ = g_list_append (NULL, $1); - } - | attribute_list COMMA attribute - { - $$ = g_list_append ($1, $3); - } - ; - -attribute - : type_name attribute_arguments - { - $$ = g_new0 (ValaAnnotation, 1); - $$->type = $1; - $$->argument_list = $2; - } - ; - -attribute_arguments - : OPEN_PARENS opt_named_argument_list CLOSE_PARENS - { - $$ = $2; - } - ; - -%% - -extern FILE *yyin; -extern int yylineno; - -void yyerror (YYLTYPE *locp, const char *s) -{ - printf ("%s:%d:%d-%d: %s\n", current_source_file->filename, locp->first_line, locp->first_column, locp->last_column, s); -} - -void vala_parser_parse (ValaSourceFile *source_file) -{ - current_source_file = source_file; - current_namespace = source_file->root_namespace; - yyin = fopen (source_file->filename, "r"); - if (yyin == NULL) { - printf ("Couldn't open source file: %s.\n", source_file->filename); - return; - } - - /* restart line counter on each file */ - yylineno = 1; - - yyparse (); - fclose (yyin); - yyin = NULL; -} diff --git a/vala/valac/scanner.l b/vala/valac/scanner.l deleted file mode 100644 index 595daa2..0000000 --- a/vala/valac/scanner.l +++ /dev/null @@ -1,134 +0,0 @@ -/* scanner.l - * - * Copyright (C) 2006 Jürg Billeter, Raffaele Sandrini - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: - * Jürg Billeter - * Raffaele Sandrini - */ - -%{ -#include "context.h" -#include "parser.h" - -#define uploc { yylloc->first_column = yylloc->last_column + 1; yylloc->last_column += strlen (yytext); } -%} - -%option yylineno -%option bison-bridge -%option bison-locations -%option noyywrap - -%x COMMENT - -space [ \t\n]* -ident [[:alnum:]_]+ -literal_integer [[:digit:]]+ -literal_character \'([^\'\\]|\\[\'\"\?\\abfnrtv])*\' -literal_string \"([^\"\\]|\\[\'\"\?\\abfnrtv])*\" -literal ({literal_integer}|{literal_character}|{literal_string}) - -%% - -"/*" { uploc; BEGIN (COMMENT); } -. { uploc; } -\n { yylloc->first_line = yylloc->last_line = yylineno; yylloc->first_column = 1; yylloc->last_column = 0; } -"*/" { uploc; BEGIN (INITIAL); } - -"//".* { uploc; } - -"{" { uploc; return OPEN_BRACE; } -"}" { uploc; return CLOSE_BRACE; } -"("{space}{ident}("."{ident})?{space}")"{space}("("|{ident}|{literal}) { yyless (1); uploc; return OPEN_CAST_PARENS; } -"(" { uploc; return OPEN_PARENS; } -")" { uploc; return CLOSE_PARENS; } -"[" { uploc; return OPEN_BRACKET; } -"]" { uploc; return CLOSE_BRACKET; } -"." { uploc; return DOT; } -":" { uploc; return COLON; } -"," { uploc; return COMMA; } -";" { uploc; return SEMICOLON; } -"#" { uploc; return HASH; } - -"|=" { uploc; return ASSIGN_BITWISE_OR; } - -"++" { uploc; return OP_INC; } -"--" { uploc; return OP_DEC; } -"==" { uploc; return OP_EQ; } -"!=" { uploc; return OP_NE; } -"<=" { uploc; return OP_LE; } -">=" { uploc; return OP_GE; } -"<" { uploc; return OP_LT; } -">" { uploc; return OP_GT; } -"!" { uploc; return OP_NEG; } -"&&" { uploc; return OP_AND; } -"&" { uploc; return BITWISE_AND; } -"||" { uploc; return OP_OR; } -"|" { uploc; return BITWISE_OR; } - -"=" { uploc; return ASSIGN; } -"+" { uploc; return PLUS; } -"-" { uploc; return MINUS; } -"*" { uploc; return STAR; } -"/" { uploc; return DIV; } - -"@"[[:alnum:]_]+ { uploc; yylval->str = strdup (yytext + 1); return IDENTIFIER; } - -"abstract" { uploc; return ABSTRACT; } -"class" { uploc; return CLASS; } -"const" { uploc; return CONST; } -"construct" { uploc; return CONSTRUCT; } -"else" { uploc; return ELSE; } -"enum" { uploc; return ENUM; } -"false" { uploc; return VALA_FALSE; } -"flags" { uploc; return FLAGS; } -"for" { uploc; return FOR; } -"foreach" { uploc; return FOREACH; } -"get" { uploc; return GET; } -"if" { uploc; return IF; } -"in" { uploc; return IN; } -"interface" { uploc; return INTERFACE; } -"is" { uploc; return IS; } -"namespace" { uploc; return NAMESPACE; } -"null" { uploc; return VALA_NULL; } -"out" { uploc; return OUT; } -"override" { uploc; return OVERRIDE; } -"public" { uploc; return PUBLIC; } -"private" { uploc; return PRIVATE; } -"readonly" { uploc; return READONLY; } -"ref" { uploc; return REF; } -"set" { uploc; return SET; } -"static" { uploc; return STATIC; } -"struct" { uploc; return STRUCT; } -"return" { uploc; return RETURN; } -"this" { uploc; return THIS; } -"true" { uploc; return VALA_TRUE; } -"using" { uploc; return USING; } -"var" { uploc; return VAR; } -"virtual" { uploc; return VIRTUAL; } -"weak" { uploc; return WEAK; } -"while" { uploc; return WHILE; } - -{literal_integer} { uploc; yylval->str = strdup (yytext); return LITERAL_INTEGER; } - -{literal_character} { uploc; yylval->str = strdup (yytext); return LITERAL_CHARACTER; } -{literal_string} { uploc; yylval->str = strdup (yytext); return LITERAL_STRING; } - -[[:alnum:]_]+ { uploc; yylval->str = strdup (yytext); return IDENTIFIER; } - -[ \t]+ { uploc; /* eat up whitespace */ } -[\n]+ { yylloc->first_line = yylloc->last_line = yylineno; yylloc->first_column = 1; yylloc->last_column = 0; } diff --git a/vala/vapi/Makefile.am b/vala/vapi/Makefile.am new file mode 100644 index 0000000..4c092f3 --- /dev/null +++ b/vala/vapi/Makefile.am @@ -0,0 +1,7 @@ +NULL = + +vapidir = $(pkgdatadir)/vapi + +dist_vapi_DATA = \ + glib-2.0.vala + $(NULL) diff --git a/vala/bindings/glib-2.0.vala b/vala/vapi/glib-2.0.vala similarity index 94% rename from vala/bindings/glib-2.0.vala rename to vala/vapi/glib-2.0.vala index 2ec8d53..44ecf0d 100644 --- a/vala/bindings/glib-2.0.vala +++ b/vala/vapi/glib-2.0.vala @@ -111,7 +111,7 @@ public struct astring { [CCode (cname = "g_str_has_suffix")] public bool has_suffix (string suffix); [CCode (cname = "g_strdup_printf")] - public ref astring printf (string args); + public ref astring printf (...); [CCode (cname = "g_ascii_strup")] public ref astring up (long len /* = -1 */); [CCode (cname = "g_ascii_strdown")] @@ -136,9 +136,9 @@ public struct string { [CCode (cname = "g_str_has_suffix")] public bool has_suffix (string suffix); [CCode (cname = "g_strdup_printf")] - public ref string printf (string args); + public ref string printf (...); [CCode (cname = "g_strconcat")] - public ref string concat (string string2); + public ref string concat (string string2, ...); [CCode (cname = "g_strndup")] public ref string ndup (int n); [CCode (cname = "g_strcompress")] @@ -174,7 +174,7 @@ namespace GLib { public struct Path { public static ref string get_basename (string file_name); [CCode (cname = "g_build_filename")] - public static ref string build_filename (string first_element); + public static ref string build_filename (string first_element, ...); } public struct Type { @@ -194,13 +194,21 @@ namespace GLib { public static void return_if_fail (bool expr); + public enum FileTest { + IS_REGULAR, + IS_SYMLINK, + IS_DIR, + IS_EXECUTABLE, + EXISTS + } + [ReferenceType ()] [CCode (cname = "FILE", cheader_filename = "stdio.h")] public struct File { [CCode (cname = "fopen")] public static ref File open (string path, string mode); [CCode (cname = "fprintf")] - public void printf (string format); + public void printf (string format, ...); [InstanceLast ()] [CCode (cname = "fputc")] public void putc (char c); @@ -209,10 +217,15 @@ namespace GLib { public void puts (string s); [CCode (cname = "fclose")] public void close (); + + public static bool test (string filename, FileTest test); } + [CCode (cname = "stdout", cheader_filename = "stdio.h")] + public static File stdout; + [CCode (cname = "stderr", cheader_filename = "stdio.h")] - public static GLib.File stderr; + public static File stderr; [Unknown (reference_type = true)] [ReferenceType ()]