From: Jürg Billeter Date: Tue, 25 Apr 2006 21:17:43 +0000 (+0000) Subject: save cname in class, save location of statements and expressions add X-Git-Tag: VALA_0_0_1~74 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8e1dd453ab18dfb06bfacc91a93a5c1c2fa2d5ed;p=platform%2Fupstream%2Fvala.git save cname in class, save location of statements and expressions add 2006-04-25 Jürg Billeter * valac/parser.y: save cname in class, save location of statements and expressions * valac/context.h: add ValaStruct struct * valac/context.c: support symbols from methods and structs, add int and string fundamental types, resolve types in local variable declarations * valac/generator.h: save pointer to current method block * valac/generator.c: add special handling for main method, basic support for method invocations, literals, member access, simple names, additive expressions, return statments, blocks * tests/test-005.vala: test static method invocation, literal integer, simple name, additive expression, return statement, block, main method svn path=/trunk/; revision=5 --- diff --git a/vala/ChangeLog b/vala/ChangeLog index ee8e8ff..dd70e70 100644 --- a/vala/ChangeLog +++ b/vala/ChangeLog @@ -1,3 +1,18 @@ +2006-04-25 Jürg Billeter + + * valac/parser.y: save cname in class, save location of statements and + expressions + * valac/context.h: add ValaStruct struct + * valac/context.c: support symbols from methods and structs, add int + and string fundamental types, resolve types in local variable + declarations + * valac/generator.h: save pointer to current method block + * valac/generator.c: add special handling for main method, basic support + for method invocations, literals, member access, simple names, + additive expressions, return statments, blocks + * tests/test-005.vala: test static method invocation, literal integer, + simple name, additive expression, return statement, block, main method + 2006-04-24 Jürg Billeter * valac/scanner.l: support single-line comments, ASSIGN, PLUS, RETURN, diff --git a/vala/tests/test-005.vala b/vala/tests/test-005.vala new file mode 100644 index 0000000..ab2ef53 --- /dev/null +++ b/vala/tests/test-005.vala @@ -0,0 +1,14 @@ +namespace Maman { + class Bar { + public static int do_action (int i) { + return (i + 42); + } + } + + class SubBar : Bar { + public static int main (int argc, string[] argv) { + int i = do_action (42); + return (argc + i); + } + } +} diff --git a/vala/valac/context.c b/vala/valac/context.c index c39a28b..983c03f 100644 --- a/vala/valac/context.c +++ b/vala/valac/context.c @@ -49,7 +49,7 @@ vala_context_parse (ValaContext *context) } } -static ValaSymbol * +ValaSymbol * vala_symbol_new (ValaSymbolType type) { ValaSymbol *symbol; @@ -59,7 +59,7 @@ vala_symbol_new (ValaSymbolType type) return symbol; } -static void +void err (ValaLocation *location, const char *format, ...) { va_list args; @@ -72,6 +72,67 @@ err (ValaLocation *location, const char *format, ...) } static void +vala_context_add_symbols_from_method (ValaContext *context, ValaSymbol *class_symbol, ValaMethod *method) +{ + ValaSymbol *method_symbol; + + 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_class (ValaContext *context, ValaClass *class) +{ + ValaSymbol *ns_symbol, *class_symbol; + ns_symbol = class->namespace->symbol; + GList *ml; + + 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 (ml = class->methods; ml != NULL; ml = ml->next) { + vala_context_add_symbols_from_method (context, class_symbol, ml->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; + + 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; +} + +static void vala_context_add_symbols_from_namespace (ValaContext *context, ValaNamespace *namespace) { ValaSymbol *ns_symbol, *class_symbol; @@ -90,16 +151,11 @@ vala_context_add_symbols_from_namespace (ValaContext *context, ValaNamespace *na namespace->symbol = ns_symbol; for (cl = namespace->classes; cl != NULL; cl = cl->next) { - ValaClass *class = cl->data; - - 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", 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); + 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); } } @@ -109,13 +165,36 @@ vala_context_add_fundamental_symbols (ValaContext *context) ValaSymbol *symbol; ValaNamespace *namespace; ValaClass *class; + ValaStruct *struct_; 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); + /* int */ + struct_ = g_new0 (ValaStruct, 1); + struct_->name = g_strdup ("int"); + struct_->namespace = namespace; + struct_->cname = g_strdup ("int"); + namespace->structs = g_list_append (namespace->structs, struct_); + + /* string */ + struct_ = g_new0 (ValaStruct, 1); + struct_->name = g_strdup ("string"); + struct_->reference_type = TRUE; + struct_->namespace = namespace; + struct_->cname = g_strdup ("char"); + namespace->structs = g_list_append (namespace->structs, struct_); + + vala_context_add_symbols_from_namespace (context, namespace); + /* namespace G */ namespace = g_new0 (ValaNamespace, 1); namespace->name = g_strdup ("G"); @@ -185,7 +264,7 @@ vala_context_resolve_type_reference (ValaContext *context, ValaNamespace *namesp err (type_reference->location, "error: specified namespace '%s' not found", type_reference->namespace_name); } - type_symbol = g_hash_table_lookup (namespace->symbol->symbol_table, 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); @@ -193,7 +272,8 @@ vala_context_resolve_type_reference (ValaContext *context, ValaNamespace *namesp } if (type_symbol->type == VALA_SYMBOL_TYPE_VOID || - type_symbol->type == VALA_SYMBOL_TYPE_CLASS) { + type_symbol->type == VALA_SYMBOL_TYPE_CLASS || + type_symbol->type == VALA_SYMBOL_TYPE_STRUCT) { type_reference->symbol = type_symbol; } else { err (type_reference->location, "error: specified symbol ´%s´ is not a type", type_reference->type_name); @@ -201,6 +281,26 @@ vala_context_resolve_type_reference (ValaContext *context, ValaNamespace *namesp } static void +vala_context_resolve_types_in_statement (ValaContext *context, ValaNamespace *namespace, ValaStatement *stmt) +{ + switch (stmt->type) { + case VALA_STATEMENT_TYPE_VARIABLE_DECLARATION: + vala_context_resolve_type_reference (context, namespace, stmt->variable_declaration->type); + 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, l->data); + } +} + +static void vala_context_resolve_types_in_method (ValaContext *context, ValaMethod *method) { GList *l; @@ -215,6 +315,10 @@ vala_context_resolve_types_in_method (ValaContext *context, ValaMethod *method) 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 diff --git a/vala/valac/context.h b/vala/valac/context.h index d81a493..f3866c1 100644 --- a/vala/valac/context.h +++ b/vala/valac/context.h @@ -34,6 +34,7 @@ typedef struct _ValaSourceFile ValaSourceFile; typedef struct _ValaLocation ValaLocation; typedef struct _ValaNamespace ValaNamespace; typedef struct _ValaClass ValaClass; +typedef struct _ValaStruct ValaStruct; typedef struct _ValaMethod ValaMethod; typedef struct _ValaStatement ValaStatement; typedef struct _ValaVariableDeclaration ValaVariableDeclaration; @@ -47,6 +48,10 @@ enum _ValaSymbolType { VALA_SYMBOL_TYPE_NAMESPACE, VALA_SYMBOL_TYPE_VOID, VALA_SYMBOL_TYPE_CLASS, + VALA_SYMBOL_TYPE_STRUCT, + VALA_SYMBOL_TYPE_METHOD, + VALA_SYMBOL_TYPE_BLOCK, + VALA_SYMBOL_TYPE_LOCAL_VARIABLE, }; enum _ValaMethodFlags { @@ -87,6 +92,10 @@ struct _ValaSymbol { ValaSymbolType type; union { ValaClass *class; + ValaStruct *struct_; + ValaMethod *method; + ValaStatement *stmt; + ValaTypeReference *typeref; }; GHashTable *symbol_table; }; @@ -107,6 +116,7 @@ struct _ValaNamespace { char *name; ValaSymbol *symbol; GList *classes; + GList *structs; char *lower_case_cname; char *upper_case_cname; }; @@ -114,21 +124,34 @@ struct _ValaNamespace { struct _ValaClass { char *name; ValaLocation *location; + ValaSymbol *symbol; ValaNamespace *namespace; ValaClass *base_class; GList *base_types; GList *methods; + char *cname; char *lower_case_cname; char *upper_case_cname; }; +struct _ValaStruct { + char *name; + ValaLocation *location; + ValaSymbol *symbol; + ValaNamespace *namespace; + gboolean reference_type; + char *cname; +}; + struct _ValaMethod { char *name; ValaLocation *location; + ValaSymbol *symbol; ValaClass *class; ValaTypeReference *return_type; GList *formal_parameters; ValaMethodFlags modifiers; + char *cname; char *cdecl1; char *cdecl2; ValaStatement *body; @@ -136,6 +159,10 @@ struct _ValaMethod { struct _ValaStatement { ValaStatementType type; + ValaLocation *location; + union { + ValaSymbol *method; + }; union { struct { GList *statements; @@ -158,6 +185,8 @@ struct _ValaVariableDeclarator { struct _ValaExpression { ValaExpressionType type; + ValaLocation *location; + ValaSymbol *static_type_symbol; union { char *str; ValaExpression *inner; @@ -173,6 +202,7 @@ struct _ValaExpression { struct { ValaExpression *call; GList *argument_list; + ValaExpression *instance; } invocation; struct { ValaExpression *left; @@ -204,3 +234,7 @@ void vala_context_resolve_types (ValaContext *context); ValaSourceFile *vala_source_file_new (const char *filename); void vala_parser_parse (ValaSourceFile *source_file); + +ValaSymbol *vala_symbol_new (ValaSymbolType type); + +void err (ValaLocation *location, const char *format, ...); diff --git a/vala/valac/generator.c b/vala/valac/generator.c index 4498668..aad37a1 100644 --- a/vala/valac/generator.c +++ b/vala/valac/generator.c @@ -20,6 +20,7 @@ * Jürg Billeter */ +#include #include #include @@ -54,6 +55,22 @@ filename_to_define (const char *filename) return define; } +static char * +get_cname_for_type_symbol (ValaSymbol *sym, ValaLocation *location) +{ + switch (sym->type) { + case VALA_SYMBOL_TYPE_CLASS: + return g_strdup_printf ("%s *", sym->class->cname); + case VALA_SYMBOL_TYPE_STRUCT: + return g_strdup_printf ("%s %s", sym->struct_->cname, (sym->struct_->reference_type ? "*" : "")); + case VALA_SYMBOL_TYPE_VOID: + return g_strdup ("void"); + default: + err (location, "internal error: symbol type %d is not a type symbol", sym->type); + return NULL; + } +} + static void vala_code_generator_process_methods1 (ValaCodeGenerator *generator, ValaClass *class) { @@ -74,18 +91,26 @@ vala_code_generator_process_methods1 (ValaCodeGenerator *generator, ValaClass *c for (l = class->methods; l != NULL; l = l->next) { ValaMethod *method = l->data; - char *method_return_type_cname = g_strdup_printf ("%s%s", method->return_type->namespace_name, method->return_type->type_name); - char *method_cname = g_strdup_printf ("%s%s_%s", ns_lower, lower_case, method->name); + char *method_return_type_cname = get_cname_for_type_symbol (method->return_type->symbol, method->location); + if ((method->modifiers & VALA_METHOD_STATIC) && strcmp (method->name, "main") == 0 && strcmp (method->return_type->type_name, "int") == 0) { + if (g_list_length (method->formal_parameters) == 2) { + method->cname = g_strdup ("main"); + } + } + 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_METHOD_STATIC) == 0) { - parameter_list = g_list_append (parameter_list, g_strdup_printf ("%s%s *self", namespace->name, class->name)); + 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; - parameter_list = g_list_append (parameter_list, g_strdup_printf ("%s%s *%s", param->type->symbol->class->namespace->name, param->type->symbol->class->name, param->name)); + char *param_string = g_strdup_printf ("%s%s", get_cname_for_type_symbol (param->type->symbol, param->location), param->name); + parameter_list = g_list_append (parameter_list, param_string); } if (parameter_list == NULL) { @@ -100,7 +125,7 @@ vala_code_generator_process_methods1 (ValaCodeGenerator *generator, ValaClass *c g_list_free (parameter_list); } - method->cdecl2 = g_strdup_printf ("%s (%s)", method_cname, parameters); + method->cdecl2 = g_strdup_printf ("%s (%s)", method->cname, parameters); if (method->modifiers & VALA_METHOD_PUBLIC) { method->cdecl1 = g_strdup (method_return_type_cname); @@ -113,6 +138,284 @@ vala_code_generator_process_methods1 (ValaCodeGenerator *generator, ValaClass *c fprintf (generator->c_file, "\n"); } +static void vala_code_generator_process_expression (ValaCodeGenerator *generator, ValaExpression *expr); + +static void +vala_code_generator_process_additive_expression (ValaCodeGenerator *generator, ValaExpression *expr) +{ + vala_code_generator_process_expression (generator, expr->additive.left); + fprintf (generator->c_file, " + "); + vala_code_generator_process_expression (generator, expr->additive.right); +} + +static void +vala_code_generator_process_assignment (ValaCodeGenerator *generator, ValaExpression *expr) +{ + 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_process_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; + } + fprintf (generator->c_file, " ("); + if ((method->modifiers & VALA_METHOD_STATIC) == 0) { + if (expr->invocation.instance != NULL) { + vala_code_generator_process_expression (generator, expr->invocation.instance); + } else { + fprintf (generator->c_file, "self"); + } + 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); + } + fprintf (generator->c_file, ")"); +} + +static void +vala_code_generator_process_literal (ValaCodeGenerator *generator, ValaExpression *expr) +{ + fprintf (generator->c_file, "%s", expr->str); +} + +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) { + return sym; + } + + if (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_ADDITIVE: + break; + case VALA_EXPRESSION_TYPE_ASSIGNMENT: + break; + case VALA_EXPRESSION_TYPE_INVOCATION: + vala_code_generator_find_static_type_of_expression (generator, expr->invocation.call); + expr->static_type_symbol = expr->invocation.call->static_type_symbol->method->return_type->symbol; + 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); + } else if (sym != NULL && sym->type == VALA_SYMBOL_TYPE_LOCAL_VARIABLE) { + } else { + err (expr->member_access.left->location, "error: specified expression type %d can't be used for member access", sym->type); + } + 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: + case VALA_EXPRESSION_TYPE_LITERAL_STRING: + break; + case VALA_EXPRESSION_TYPE_SIMPLE_NAME: + if (strcmp (expr->str, "this") == 0) { + expr->static_type_symbol = generator->sym->stmt->method->method->class->symbol; + } + + if (expr->static_type_symbol == NULL) { + /* local variable */ + sym = g_hash_table_lookup (generator->sym->symbol_table, expr->str); + if (sym != NULL) { + expr->static_type_symbol = sym->typeref->symbol; + } + } + + if (expr->static_type_symbol == NULL) { + /* member of this */ + expr->static_type_symbol = get_inherited_member (generator->sym->stmt->method->method->class->symbol, expr->str, expr->location, FALSE); + } + + if (expr->static_type_symbol == NULL) { + /* member of this */ + expr->static_type_symbol = g_hash_table_lookup (generator->context->root->symbol_table, expr->str); + } + + if (expr->static_type_symbol == NULL) { + err (expr->location, "error: symbol ´%s´ not found", expr->str); + } + break; + } +} + +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 { + vala_code_generator_process_expression (generator, expr->member_access.left); + fprintf (generator->c_file, "->%s", expr->member_access.right); + } +} + +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_simple_name (ValaCodeGenerator *generator, ValaExpression *expr) +{ + 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_expression (ValaCodeGenerator *generator, ValaExpression *expr) +{ + vala_code_generator_find_static_type_of_expression (generator, expr); + + switch (expr->type) { + case VALA_EXPRESSION_TYPE_ADDITIVE: + vala_code_generator_process_additive_expression (generator, expr); + break; + case VALA_EXPRESSION_TYPE_ASSIGNMENT: + vala_code_generator_process_assignment (generator, expr); + break; + case VALA_EXPRESSION_TYPE_INVOCATION: + vala_code_generator_process_invocation (generator, expr); + break; + case VALA_EXPRESSION_TYPE_MEMBER_ACCESS: + vala_code_generator_process_member_access (generator, expr); + break; + case VALA_EXPRESSION_TYPE_PARENTHESIZED: + vala_code_generator_process_parenthesized_expression (generator, expr); + break; + case VALA_EXPRESSION_TYPE_LITERAL_INTEGER: + 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; + } +} + +static void +vala_code_generator_process_variable_declaration (ValaCodeGenerator *generator, ValaStatement *stmt) +{ + ValaSymbol *sym = stmt->variable_declaration->type->symbol; + + char *decl_string = get_cname_for_type_symbol (sym, stmt->location); + + fprintf (generator->c_file, "\t%s%s", decl_string, stmt->variable_declaration->declarator->name); + + ValaExpression *expr = stmt->variable_declaration->declarator->initializer; + if (expr != NULL) { + fprintf (generator->c_file, " = "); + vala_code_generator_process_expression (generator, expr); + } + + fprintf (generator->c_file, ";\n"); + + 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_return_statement (ValaCodeGenerator *generator, ValaStatement *stmt) +{ + GList *l; + + fprintf (generator->c_file, "\treturn "); + 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_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 void vala_code_generator_process_methods2 (ValaCodeGenerator *generator, ValaClass *class) { @@ -139,8 +442,25 @@ vala_code_generator_process_methods2 (ValaCodeGenerator *generator, ValaClass *c fprintf (generator->c_file, "%s\n", method->cdecl1); fprintf (generator->c_file, "%s\n", method->cdecl2); - fprintf (generator->c_file, "{\n"); - fprintf (generator->c_file, "}\n"); + + if (method->body != NULL) { + 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); + } + fprintf (generator->c_file, "\n"); } fprintf (generator->h_file, "\n"); diff --git a/vala/valac/generator.h b/vala/valac/generator.h index 1f03aa2..be7cd9f 100644 --- a/vala/valac/generator.h +++ b/vala/valac/generator.h @@ -29,6 +29,7 @@ struct _ValaCodeGenerator { const char *directory; FILE *c_file; FILE *h_file; + ValaSymbol *sym; /* current block */ }; ValaCodeGenerator *vala_code_generator_new (ValaContext *context); diff --git a/vala/valac/parser.y b/vala/valac/parser.y index f356d0a..5c28426 100644 --- a/vala/valac/parser.y +++ b/vala/valac/parser.y @@ -248,6 +248,7 @@ class_declaration current_class->base_types = $3; current_class->location = current_location (@2); current_class->namespace = current_namespace; + current_class->cname = g_strdup_printf ("%s%s", current_namespace->name, 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); @@ -421,6 +422,7 @@ block { $$ = g_new0 (ValaStatement, 1); $$->type = VALA_STATEMENT_TYPE_BLOCK; + $$->location = current_location (@1); $$->block.statements = $2; } ; @@ -463,6 +465,7 @@ declaration_statement { $$ = g_new0 (ValaStatement, 1); $$->type = VALA_STATEMENT_TYPE_VARIABLE_DECLARATION; + $$->location = current_location (@1); $$->variable_declaration = $1;; } ; @@ -528,6 +531,7 @@ additive_expression { $$ = g_new0 (ValaExpression, 1); $$->type = VALA_EXPRESSION_TYPE_ADDITIVE; + $$->location = current_location (@1); $$->additive.left = $1; $$->additive.op = VALA_OP_TYPE_PLUS; $$->additive.right = $3; @@ -562,12 +566,14 @@ literal { $$ = 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; } ; @@ -577,6 +583,7 @@ simple_name { $$ = g_new0 (ValaExpression, 1); $$->type = VALA_EXPRESSION_TYPE_SIMPLE_NAME; + $$->location = current_location (@1); $$->str = $1; } ; @@ -586,6 +593,7 @@ parenthesized_expression { $$ = g_new0 (ValaExpression, 1); $$->type = VALA_EXPRESSION_TYPE_PARENTHESIZED; + $$->location = current_location (@1); $$->inner = $2; } ; @@ -595,6 +603,7 @@ member_access { $$ = g_new0 (ValaExpression, 1); $$->type = VALA_EXPRESSION_TYPE_MEMBER_ACCESS; + $$->location = current_location (@1); $$->member_access.left = $1; $$->member_access.right = $3; } @@ -605,6 +614,7 @@ invocation_expression { $$ = g_new0 (ValaExpression, 1); $$->type = VALA_EXPRESSION_TYPE_INVOCATION; + $$->location = current_location (@1); $$->invocation.call = $1; $$->invocation.argument_list = $3; } @@ -667,6 +677,7 @@ expression_statement { $$ = g_new0 (ValaStatement, 1); $$->type = VALA_STATEMENT_TYPE_EXPRESSION; + $$->location = current_location (@1); $$->expr = $1; } ; @@ -687,6 +698,7 @@ assignment { $$ = g_new0 (ValaExpression, 1); $$->type = VALA_EXPRESSION_TYPE_ASSIGNMENT; + $$->location = current_location (@1); $$->assignment.left = $1; $$->assignment.right = $3; } @@ -704,6 +716,7 @@ return_statement { $$ = g_new0 (ValaStatement, 1); $$->type = VALA_STATEMENT_TYPE_RETURN; + $$->location = current_location (@1); $$->expr = $2; } ; @@ -711,6 +724,7 @@ return_statement %% extern FILE *yyin; +extern int yylineno; void yyerror (YYLTYPE *locp, const char *s) { @@ -726,6 +740,10 @@ void vala_parser_parse (ValaSourceFile *source_file) 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;