+2006-05-25 Jürg Billeter <j@bitron.ch>
+
+ * 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 <j@bitron.ch>
Compiler is now self-hosting.
NULL =
SUBDIRS = \
- valac \
+ ccode \
+ vala \
+ compiler \
+ vapi \
$(NULL)
--- /dev/null
+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
namespace Vala {
public class CCodeBlock : CCodeStatement {
List<CCodeNode> statements;
+ public bool suppress_newline;
public void add_statement (CCodeNode statement) {
/* allow generic nodes to include comments */
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 ();
+ }
}
}
}
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);
}
}
public void write_begin_block () {
if (!bol) {
stream.putc (' ');
+ } else {
+ write_indent ();
}
stream.putc ('{');
write_newline ();
--- /dev/null
+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)
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) {
}
var compiler = new Compiler ();
- compiler.run ();
-
- return 0;
+ return compiler.run ();
}
}
}
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
--- /dev/null
+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
%token CLOSE_PARENS ")"
%token OPEN_BRACKET "["
%token CLOSE_BRACKET "]"
+%token ELLIPSIS "..."
%token DOT "."
%token COLON ":"
%token COMMA ","
%%
+opt_comma
+ : /* empty */
+ | COMMA
+ ;
+
literal
: boolean_literal
| INTEGER_LITERAL
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);
}
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
vala_struct_add_type_parameter ($$, l->data);
}
VALA_CODE_NODE($$)->attributes = $2;
+ if ($3 != 0) {
+ VALA_TYPE_($$)->access = $3;
+ }
}
;
{
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);
}
{
$$ = NULL;
}
- | enum_member_declarations
+ | enum_member_declarations opt_comma
;
enum_member_declarations
")" { uploc; return CLOSE_PARENS; }
"[" { uploc; return OPEN_BRACKET; }
"]" { uploc; return CLOSE_BRACKET; }
+"..." { uploc; return ELLIPSIS; }
"." { uploc; return DOT; }
":" { uploc; return COLON; }
"," { uploc; return COMMA; }
"/" { 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; }
public class Class : Struct {
public List<TypeReference> base_types;
public Class base_class;
+ public bool is_abstract;
List<Property> properties;
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 ();
}
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) {
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 ();
} 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);
} 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;
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));
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);
}
--- /dev/null
+/* 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 <j@bitron.ch>
+ */
+
+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 ("}");
+ }
+ }
+}
namespace Vala {
public enum MemberAccessibility {
PRIVATE,
+ INTERNAL,
PUBLIC
}
}
public bool is_abstract;
public bool is_virtual;
public bool is_override;
- List<FormalParameter> parameters;
+ public List<FormalParameter> 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));
}
} 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;
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));
}
--- /dev/null
+/* 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 <j@bitron.ch>
+ */
+
+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);
+ }
+ }
+ }
+}
SourceFile current_source_file;
List<NamespaceReference> current_using_directives;
- TypeReference dummy; // required for broken dependency handlind
public void analyze (CodeContext context) {
root_symbol = context.root;
}
}
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);
+ }
}
}
}
public override void visit_null_literal (NullLiteral expr) {
+ expr.static_type = new TypeReference ();
}
public override void visit_literal_expression (LiteralExpression expr) {
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;
} 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;
}
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);
}
}
- 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) {
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);
Namespace global_namespace;
List<Namespace> 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));
}
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;
HashTable<string,Symbol> 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) {
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);
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);
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);
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);
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);
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);
}
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);
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);
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;
}
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;
}
}
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;
} 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;
}
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 ();
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;
}
}
+++ /dev/null
-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)
+++ /dev/null
-/* 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 <j@bitron.ch>
- * Raffaele Sandrini <rasa@gmx.ch>
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <glib.h>
-
-#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;
-}
+++ /dev/null
-/* 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 <j@bitron.ch>
- * Raffaele Sandrini <rasa@gmx.ch>
- */
-
-#include <glib.h>
-
-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, ...);
+++ /dev/null
-/* driver.c
- *
- * Copyright (C) 2006 Jürg Billeter <j@bitron.ch>
- *
- * 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 <j@bitron.ch>
- */
-
-#include <glib.h>
-
-#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);
-}
+++ /dev/null
-/* 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 <j@bitron.ch>
- * Raffaele Sandrini <rasa@gmx.ch>
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <glib.h>
-
-#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 <stdio.h>\n");
- fprintf (generator->h_file, "#include <string.h>\n");
- fprintf (generator->h_file, "#include <glib-object.h>\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);
-}
+++ /dev/null
-/* generator.h
- *
- * Copyright (C) 2006 Jürg Billeter <j@bitron.ch>
- *
- * 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 <j@bitron.ch>
- */
-
-#include <stdio.h>
-
-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);
+++ /dev/null
-/* 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 <j@bitron.ch>
- * Raffaele Sandrini <rasa@gmx.ch>
- */
-
-%{
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <glib.h>
-
-#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 <str> IDENTIFIER "identifier"
-%token <str> LITERAL_CHARACTER "character"
-%token <str> LITERAL_INTEGER "integer"
-%token <str> LITERAL_STRING "string"
-
-%type <list> opt_type_parameter_list
-%type <list> type_parameter_list
-%type <list> type_parameters
-%type <list> opt_type_argument_list
-%type <list> type_argument_list
-%type <list> type_arguments
-%type <list> opt_class_base
-%type <list> class_base
-%type <list> type_list
-%type <list> opt_formal_parameter_list
-%type <list> formal_parameter_list
-%type <list> fixed_parameters
-%type <list> opt_statement_list
-%type <list> statement_list
-%type <list> opt_argument_list
-%type <list> argument_list
-%type <list> opt_named_argument_list
-%type <list> named_argument_list
-%type <list> opt_statement_expression_list
-%type <list> statement_expression_list
-%type <list> opt_variable_initializer_list
-%type <list> variable_initializer_list
-%type <num> opt_modifiers
-%type <num> modifiers
-%type <num> modifier
-%type <num> opt_parameter_modifier
-%type <num> parameter_modifier
-%type <bool> opt_at
-%type <bool> opt_brackets
-%type <bool> boolean_literal
-%type <type_reference> type_name
-%type <expression> variable_initializer
-%type <expression> opt_expression
-%type <expression> expression
-%type <expression> additive_expression
-%type <expression> multiplicative_expression
-%type <expression> unary_expression
-%type <expression> cast_expression
-%type <expression> assignment
-%type <expression> primary_expression
-%type <expression> literal
-%type <expression> simple_name
-%type <expression> parenthesized_expression
-%type <expression> member_access
-%type <expression> invocation_expression
-%type <expression> element_access
-%type <expression> this_access
-%type <expression> statement_expression
-%type <expression> argument
-%type <expression> object_creation_expression
-%type <expression> equality_expression
-%type <expression> relational_expression
-%type <expression> and_expression
-%type <expression> inclusive_or_expression
-%type <expression> conditional_and_expression
-%type <expression> conditional_or_expression
-%type <expression> post_increment_expression
-%type <expression> post_decrement_expression
-%type <expression> struct_or_array_initializer
-%type <statement> block
-%type <statement> statement
-%type <statement> declaration_statement
-%type <statement> embedded_statement
-%type <statement> expression_statement
-%type <statement> selection_statement
-%type <statement> if_statement
-%type <statement> iteration_statement
-%type <statement> while_statement
-%type <statement> for_statement
-%type <statement> foreach_statement
-%type <statement> jump_statement
-%type <statement> return_statement
-%type <formal_parameter> fixed_parameter
-%type <variable_declaration> variable_declaration
-%type <variable_declarator> variable_declarator
-%type <field> field_declaration
-%type <property> property_declaration
-%type <property> accessor_declarations
-%type <statement> get_accessor_declaration
-%type <statement> set_accessor_declaration
-%type <statement> accessor_body
-%type <named_argument> named_argument
-%type <constant> constant_declaration
-%type <struct_> struct_declaration
-%type <method> method_declaration
-%type <method> method_header
-%type <enum_> enum_declaration
-%type <flags> flags_declaration
-%type <list> opt_enum_member_declarations
-%type <list> enum_member_declarations
-%type <list> enum_body
-%type <enum_value> enum_member_declaration
-%type <list> opt_flags_member_declarations
-%type <list> flags_member_declarations
-%type <list> flags_body
-%type <flags_value> flags_member_declaration
-%type <list> opt_attribute_sections
-%type <list> attribute_sections
-%type <list> attribute_section
-%type <list> attribute_list
-%type <list> attribute_arguments
-%type <annotation> 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;
-}
+++ /dev/null
-/* 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 <j@bitron.ch>
- * Raffaele Sandrini <rasa@gmx.ch>
- */
-
-%{
-#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); }
-<COMMENT>. { uploc; }
-<COMMENT>\n { yylloc->first_line = yylloc->last_line = yylineno; yylloc->first_column = 1; yylloc->last_column = 0; }
-<COMMENT>"*/" { 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; }
--- /dev/null
+NULL =
+
+vapidir = $(pkgdatadir)/vapi
+
+dist_vapi_DATA = \
+ glib-2.0.vala
+ $(NULL)
[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")]
[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")]
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 {
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);
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 ()]