From: Jürg Billeter Date: Fri, 3 Aug 2012 07:38:11 +0000 (+0200) Subject: Drop Dova profile X-Git-Tag: 0.17.4~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5ea6dc05d62c71ba4e633f70b86e4dd0a5e9c089;p=thirdparty%2Fvala.git Drop Dova profile --- diff --git a/codegen/Makefile.am b/codegen/Makefile.am index 2535a88de..ac9979096 100644 --- a/codegen/Makefile.am +++ b/codegen/Makefile.am @@ -28,18 +28,6 @@ libvala_la_VALASOURCES = \ valaccodestructmodule.vala \ valaclassregisterfunction.vala \ valactype.vala \ - valadovaarraymodule.vala \ - valadovaassignmentmodule.vala \ - valadovabasemodule.vala \ - valadovacontrolflowmodule.vala \ - valadovadelegatemodule.vala \ - valadovaerrormodule.vala \ - valadovamemberaccessmodule.vala \ - valadovamethodcallmodule.vala \ - valadovamethodmodule.vala \ - valadovaobjectmodule.vala \ - valadovastructmodule.vala \ - valadovavaluemodule.vala \ valaenumregisterfunction.vala \ valagasyncmodule.vala \ valagdbusclientmodule.vala \ diff --git a/codegen/valaccodeattribute.vala b/codegen/valaccodeattribute.vala index 2ea1244e5..523ec7873 100644 --- a/codegen/valaccodeattribute.vala +++ b/codegen/valaccodeattribute.vala @@ -584,11 +584,6 @@ public class Vala.CCodeAttribute : AttributeCache { } } else if (node is ObjectType) { var type = (ObjectType) node; - if (CodeContext.get ().profile == Profile.DOVA) { - if (type.type_symbol.get_full_name () == "string") { - return "string_t"; - } - } string cname; if (!type.value_owned) { @@ -603,19 +598,11 @@ public class Vala.CCodeAttribute : AttributeCache { if (type.inline_allocated) { return cname; } else { - if (CodeContext.get ().profile == Profile.DOVA) { - return "DovaArray"; - } else { - return "%s*".printf (cname); - } + return "%s*".printf (cname); } } else if (node is DelegateType) { var type = (DelegateType) node; - if (CodeContext.get ().profile == Profile.DOVA) { - return "%s*".printf (CCodeBaseModule.get_ccode_name (type.delegate_symbol)); - } else { - return CCodeBaseModule.get_ccode_name (type.delegate_symbol); - } + return CCodeBaseModule.get_ccode_name (type.delegate_symbol); } else if (node is ErrorType) { return "GError*"; } else if (node is GenericType) { @@ -1147,14 +1134,6 @@ public class Vala.CCodeAttribute : AttributeCache { if (base_st != null) { return CCodeBaseModule.get_ccode_default_value (base_st); } - - if (CodeContext.get ().profile == Profile.DOVA) { - if (st.is_boolean_type ()) { - return "false"; - } else if (st.is_integer_type () || st.is_floating_type ()) { - return "0"; - } - } } return ""; } @@ -1178,10 +1157,6 @@ public class Vala.CCodeAttribute : AttributeCache { string infix = "construct"; - if (CodeContext.get ().profile == Profile.DOVA) { - infix = "init"; - } - if (m.name == ".new") { return "%s%s".printf (CCodeBaseModule.get_ccode_lower_case_prefix (parent), infix); } else { diff --git a/codegen/valadovaarraymodule.vala b/codegen/valadovaarraymodule.vala deleted file mode 100644 index 0246cf79a..000000000 --- a/codegen/valadovaarraymodule.vala +++ /dev/null @@ -1,90 +0,0 @@ -/* valadovaarraymodule.vala - * - * Copyright (C) 2006-2011 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.1 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 - */ - -public class Vala.DovaArrayModule : DovaMethodCallModule { - void append_initializer_list (CCodeExpression name_cnode, InitializerList initializer_list, ref int i) { - foreach (Expression e in initializer_list.get_initializers ()) { - ccode.add_assignment (new CCodeElementAccess (name_cnode, new CCodeConstant (i.to_string ())), get_cvalue (e)); - i++; - } - } - - public override void visit_array_creation_expression (ArrayCreationExpression expr) { - var array_type = expr.target_type as ArrayType; - if (array_type != null && array_type.fixed_length) { - // no heap allocation for fixed-length arrays - - var temp_var = get_temp_variable (array_type, true, expr); - var name_cnode = new CCodeIdentifier (temp_var.name); - int i = 0; - - emit_temp_var (temp_var); - - append_initializer_list (name_cnode, expr.initializer_list, ref i); - - set_cvalue (expr, name_cnode); - - return; - } - - generate_method_declaration ((Method) array_struct.scope.lookup ("create"), cfile); - - var array_new = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_create")); - array_new.add_argument (get_type_id_expression (expr.element_type)); - - // length of new array - array_new.add_argument (get_cvalue (expr.get_sizes ().get (0))); - - var temp_var = get_temp_variable (expr.value_type, true, expr); - var name_cnode = get_variable_cexpression (temp_var.name); - - emit_temp_var (temp_var); - - ccode.add_assignment (name_cnode, array_new); - - set_cvalue (expr, name_cnode); - } - - public override void visit_element_access (ElementAccess expr) { - List indices = expr.get_indices (); - - var ccontainer = get_cvalue (expr.container); - var cindex = get_cvalue (indices[0]); - - // access to element in an array - set_cvalue (expr, new CCodeElementAccess (ccontainer, cindex)); - } - - public override void visit_slice_expression (SliceExpression expr) { - var ccontainer = get_cvalue (expr.container); - var cstart = get_cvalue (expr.start); - var cstop = get_cvalue (expr.stop); - - var array_type = (ArrayType) expr.container.value_type; - - var array = new CCodeFunctionCall (new CCodeIdentifier ("dova_array")); - array.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeCastExpression (new CCodeMemberAccess (ccontainer, "data"), get_ccode_name (array_type.element_type) + "*"), cstart)); - array.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MINUS, cstop, cstart)); - - set_cvalue (expr, array); - } -} diff --git a/codegen/valadovaassignmentmodule.vala b/codegen/valadovaassignmentmodule.vala deleted file mode 100644 index 572b24cc7..000000000 --- a/codegen/valadovaassignmentmodule.vala +++ /dev/null @@ -1,155 +0,0 @@ -/* valadovaassignmentmodule.vala - * - * Copyright (C) 2006-2011 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.1 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 - */ - -/** - * The link between an assignment and generated code. - */ -public class Vala.DovaAssignmentModule : DovaMemberAccessModule { - CCodeExpression? emit_simple_assignment (Assignment assignment) { - CCodeExpression rhs = get_cvalue (assignment.right); - CCodeExpression lhs = (CCodeExpression) get_ccodenode (assignment.left); - - bool unref_old = requires_destroy (assignment.left.value_type); - - if (unref_old) { - if (!is_pure_ccode_expression (lhs)) { - /* Assign lhs to temp var to avoid repeating side effect */ - var lhs_value_type = assignment.left.value_type.copy (); - string lhs_temp_name = "_tmp%d_".printf (next_temp_var_id++); - var lhs_temp = new LocalVariable (lhs_value_type, "*" + lhs_temp_name); - emit_temp_var (lhs_temp); - ccode.add_assignment (get_variable_cexpression (lhs_temp_name), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, lhs)); - lhs = new CCodeParenthesizedExpression (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (lhs_temp_name))); - } - - var temp_decl = get_temp_variable (assignment.left.value_type); - emit_temp_var (temp_decl); - ccode.add_assignment (get_variable_cexpression (temp_decl.name), rhs); - if (unref_old) { - /* unref old value */ - ccode.add_expression (get_unref_expression (lhs, assignment.left.value_type, assignment.left)); - } - - rhs = get_variable_cexpression (temp_decl.name); - } - - var cop = CCodeAssignmentOperator.SIMPLE; - if (assignment.operator == AssignmentOperator.BITWISE_OR) { - cop = CCodeAssignmentOperator.BITWISE_OR; - } else if (assignment.operator == AssignmentOperator.BITWISE_AND) { - cop = CCodeAssignmentOperator.BITWISE_AND; - } else if (assignment.operator == AssignmentOperator.BITWISE_XOR) { - cop = CCodeAssignmentOperator.BITWISE_XOR; - } else if (assignment.operator == AssignmentOperator.ADD) { - cop = CCodeAssignmentOperator.ADD; - } else if (assignment.operator == AssignmentOperator.SUB) { - cop = CCodeAssignmentOperator.SUB; - } else if (assignment.operator == AssignmentOperator.MUL) { - cop = CCodeAssignmentOperator.MUL; - } else if (assignment.operator == AssignmentOperator.DIV) { - cop = CCodeAssignmentOperator.DIV; - } else if (assignment.operator == AssignmentOperator.PERCENT) { - cop = CCodeAssignmentOperator.PERCENT; - } else if (assignment.operator == AssignmentOperator.SHIFT_LEFT) { - cop = CCodeAssignmentOperator.SHIFT_LEFT; - } else if (assignment.operator == AssignmentOperator.SHIFT_RIGHT) { - cop = CCodeAssignmentOperator.SHIFT_RIGHT; - } - - CCodeExpression codenode = new CCodeAssignment (lhs, rhs, cop); - - ccode.add_expression (codenode); - - if (assignment.parent_node is ExpressionStatement) { - return null; - } else { - return lhs; - } - } - - CCodeExpression? emit_fixed_length_array_assignment (Assignment assignment, ArrayType array_type) { - CCodeExpression rhs = get_cvalue (assignment.right); - CCodeExpression lhs = (CCodeExpression) get_ccodenode (assignment.left); - - // it is necessary to use memcpy for fixed-length (stack-allocated) arrays - // simple assignments do not work in C - var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof")); - sizeof_call.add_argument (new CCodeIdentifier (get_ccode_name (array_type.element_type))); - var size = new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeConstant ("%d".printf (array_type.length)), sizeof_call); - var ccopy = new CCodeFunctionCall (new CCodeIdentifier ("memcpy")); - ccopy.add_argument (lhs); - ccopy.add_argument (rhs); - ccopy.add_argument (size); - - ccode.add_expression (ccopy); - - if (assignment.parent_node is ExpressionStatement) { - return null; - } else { - return lhs; - } - } - - public override void visit_assignment (Assignment assignment) { - if (assignment.left.error || assignment.right.error) { - assignment.error = true; - return; - } - - if (assignment.left.symbol_reference is Property) { - var ma = assignment.left as MemberAccess; - var prop = (Property) assignment.left.symbol_reference; - - store_property (prop, ma.inner, assignment.right.target_value); - - set_cvalue (assignment, get_ccodenode (assignment.right)); - } else { - var array_type = assignment.left.value_type as ArrayType; - if (array_type != null && array_type.fixed_length) { - set_cvalue (assignment, emit_fixed_length_array_assignment (assignment, array_type)); - } else { - set_cvalue (assignment, emit_simple_assignment (assignment)); - } - } - } - - public virtual void store_variable (Variable variable, TargetValue lvalue, TargetValue value, bool initializer) { - if (!initializer && requires_destroy (variable.variable_type)) { - /* unref old value */ - ccode.add_expression (destroy_value (lvalue)); - } - - ccode.add_assignment (get_cvalue_ (lvalue), get_cvalue_ (value)); - } - - public override void store_local (LocalVariable local, TargetValue value, bool initializer) { - store_variable (local, get_local_cvalue (local), value, initializer); - } - - public override void store_parameter (Parameter param, TargetValue value) { - store_variable (param, get_parameter_cvalue (param), value, false); - } - - public override void store_field (Field field, TargetValue? instance, TargetValue value) { - store_variable (field, get_field_cvalue (field, instance), value, false); - } -} diff --git a/codegen/valadovabasemodule.vala b/codegen/valadovabasemodule.vala deleted file mode 100644 index bb85873a7..000000000 --- a/codegen/valadovabasemodule.vala +++ /dev/null @@ -1,2407 +0,0 @@ -/* valadovabasemodule.vala - * - * Copyright (C) 2006-2011 Jürg Billeter - * Copyright (C) 2006-2008 Raffaele Sandrini - * - * 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.1 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 - * Raffaele Sandrini - */ - -/** - * Code visitor generating C Code. - */ -public abstract class Vala.DovaBaseModule : CodeGenerator { - public class EmitContext { - public Symbol? current_symbol; - public ArrayList symbol_stack = new ArrayList (); - public TryStatement current_try; - public CCodeFunction ccode; - public ArrayList ccode_stack = new ArrayList (); - public ArrayList temp_ref_vars = new ArrayList (); - public int next_temp_var_id; - public Map variable_name_map = new HashMap (str_hash, str_equal); - - public EmitContext (Symbol? symbol = null) { - current_symbol = symbol; - } - - public void push_symbol (Symbol symbol) { - symbol_stack.add (current_symbol); - current_symbol = symbol; - } - - public void pop_symbol () { - current_symbol = symbol_stack[symbol_stack.size - 1]; - symbol_stack.remove_at (symbol_stack.size - 1); - } - } - - public CodeContext context { get; set; } - - public Symbol root_symbol; - - public EmitContext emit_context = new EmitContext (); - - List emit_context_stack = new ArrayList (); - - public Symbol current_symbol { get { return emit_context.current_symbol; } } - - public TryStatement current_try { - get { return emit_context.current_try; } - set { emit_context.current_try = value; } - } - - public TypeSymbol? current_type_symbol { - get { - var sym = current_symbol; - while (sym != null) { - if (sym is TypeSymbol) { - return (TypeSymbol) sym; - } - sym = sym.parent_symbol; - } - return null; - } - } - - public Class? current_class { - get { return current_type_symbol as Class; } - } - - public Method? current_method { - get { - var sym = current_symbol; - while (sym is Block) { - sym = sym.parent_symbol; - } - return sym as Method; - } - } - - public PropertyAccessor? current_property_accessor { - get { - var sym = current_symbol; - while (sym is Block) { - sym = sym.parent_symbol; - } - return sym as PropertyAccessor; - } - } - - public DataType? current_return_type { - get { - var m = current_method; - if (m != null) { - return m.return_type; - } - - var acc = current_property_accessor; - if (acc != null) { - if (acc.readable) { - return acc.value_type; - } else { - return void_type; - } - } - - return null; - } - } - - public Block? current_closure_block { - get { - return next_closure_block (current_symbol); - } - } - - public unowned Block? next_closure_block (Symbol sym) { - unowned Block block = null; - while (true) { - block = sym as Block; - if (!(sym is Block || sym is Method)) { - // no closure block - break; - } - if (block != null && block.captured) { - // closure block found - break; - } - sym = sym.parent_symbol; - } - return block; - } - - public CCodeFile header_file; - public CCodeFile cfile; - - string? csource_filename; - - public CCodeFunction ccode { get { return emit_context.ccode; } } - - /* temporary variables that own their content */ - public ArrayList temp_ref_vars { get { return emit_context.temp_ref_vars; } } - /* (constant) hash table with all reserved identifiers in the generated code */ - Set reserved_identifiers; - - public List static_fields = new ArrayList (); - - public int next_temp_var_id { - get { return emit_context.next_temp_var_id; } - set { emit_context.next_temp_var_id = value; } - } - - public int next_wrapper_id = 0; - public bool in_creation_method { get { return current_method is CreationMethod; } } - int next_block_id = 0; - Map block_map = new HashMap (); - - public DataType void_type = new VoidType (); - public DataType bool_type; - public DataType char_type; - public DataType int_type; - public DataType uint_type; - public DataType string_type; - public Class object_class; - public Class type_class; - public Class value_class; - public Class string_class; - public Struct array_struct; - public Class delegate_class; - public Class error_class; - - Set generated_external_symbols; - - public Map variable_name_map { get { return emit_context.variable_name_map; } } - - public DovaBaseModule () { - reserved_identifiers = new HashSet (str_hash, str_equal); - - // C99 keywords - reserved_identifiers.add ("_Bool"); - reserved_identifiers.add ("_Complex"); - reserved_identifiers.add ("_Imaginary"); - reserved_identifiers.add ("auto"); - reserved_identifiers.add ("break"); - reserved_identifiers.add ("case"); - reserved_identifiers.add ("char"); - reserved_identifiers.add ("const"); - reserved_identifiers.add ("continue"); - reserved_identifiers.add ("default"); - reserved_identifiers.add ("do"); - reserved_identifiers.add ("double"); - reserved_identifiers.add ("else"); - reserved_identifiers.add ("enum"); - reserved_identifiers.add ("extern"); - reserved_identifiers.add ("float"); - reserved_identifiers.add ("for"); - reserved_identifiers.add ("goto"); - reserved_identifiers.add ("if"); - reserved_identifiers.add ("inline"); - reserved_identifiers.add ("int"); - reserved_identifiers.add ("long"); - reserved_identifiers.add ("register"); - reserved_identifiers.add ("restrict"); - reserved_identifiers.add ("return"); - reserved_identifiers.add ("short"); - reserved_identifiers.add ("signed"); - reserved_identifiers.add ("sizeof"); - reserved_identifiers.add ("static"); - reserved_identifiers.add ("struct"); - reserved_identifiers.add ("switch"); - reserved_identifiers.add ("typedef"); - reserved_identifiers.add ("union"); - reserved_identifiers.add ("unsigned"); - reserved_identifiers.add ("void"); - reserved_identifiers.add ("volatile"); - reserved_identifiers.add ("while"); - - // reserved for Vala naming conventions - reserved_identifiers.add ("result"); - reserved_identifiers.add ("this"); - } - - public override void emit (CodeContext context) { - this.context = context; - - root_symbol = context.root; - - bool_type = new BooleanType ((Struct) root_symbol.scope.lookup ("bool")); - char_type = new IntegerType ((Struct) root_symbol.scope.lookup ("char")); - int_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int")); - uint_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint")); - string_type = new ObjectType ((Class) root_symbol.scope.lookup ("string")); - - var dova_ns = (Namespace) root_symbol.scope.lookup ("Dova"); - object_class = (Class) dova_ns.scope.lookup ("Object"); - type_class = (Class) dova_ns.scope.lookup ("Type"); - value_class = (Class) dova_ns.scope.lookup ("Value"); - string_class = (Class) root_symbol.scope.lookup ("string"); - array_struct = (Struct) dova_ns.scope.lookup ("Array"); - delegate_class = (Class) dova_ns.scope.lookup ("Delegate"); - error_class = (Class) dova_ns.scope.lookup ("Error"); - - header_file = new CCodeFile (); - header_file.is_header = true; - - cfile = new CCodeFile (); - - if (context.nostdpkg) { - header_file.add_include ("dova-types.h"); - cfile.add_include ("dova-types.h"); - } else { - header_file.add_include ("dova-base.h"); - cfile.add_include ("dova-base.h"); - } - - generated_external_symbols = new HashSet (); - - - /* we're only interested in non-pkg source files */ - var source_files = context.get_source_files (); - foreach (SourceFile file in source_files) { - if (file.file_type == SourceFileType.SOURCE) { - file.accept (this); - } - } - - if (csource_filename != null) { - if (!cfile.store (csource_filename, null, context.version_header, context.debug)) { - Report.error (null, "unable to open `%s' for writing".printf (csource_filename)); - } - } - - cfile = null; - - - // generate C header file for public API - if (context.header_filename != null) { - if (!header_file.store (context.header_filename, null, context.version_header, false)) { - Report.error (null, "unable to open `%s' for writing".printf (context.header_filename)); - } - } - } - - public void push_context (EmitContext emit_context) { - if (this.emit_context != null) { - emit_context_stack.add (this.emit_context); - } - - this.emit_context = emit_context; - } - - public void pop_context () { - if (emit_context_stack.size > 0) { - this.emit_context = emit_context_stack[emit_context_stack.size - 1]; - emit_context_stack.remove_at (emit_context_stack.size - 1); - } else { - this.emit_context = null; - } - } - - public void push_function (CCodeFunction func) { - emit_context.ccode_stack.add (ccode); - emit_context.ccode = func; - } - - public void pop_function () { - emit_context.ccode = emit_context.ccode_stack[emit_context.ccode_stack.size - 1]; - emit_context.ccode_stack.remove_at (emit_context.ccode_stack.size - 1); - } - - public bool add_symbol_declaration (CCodeFile decl_space, Symbol sym, string name) { - if (decl_space.add_declaration (name)) { - return true; - } - if (sym.external_package || (!decl_space.is_header && CodeContext.get ().use_header && !sym.is_internal_symbol ())) { - // add appropriate include file - foreach (string header_filename in CCodeBaseModule.get_ccode_header_filenames (sym).split (",")) { - decl_space.add_include (header_filename, !sym.external_package); - } - // declaration complete - return true; - } else { - // require declaration - return false; - } - } - - public override void visit_source_file (SourceFile source_file) { - if (csource_filename == null) { - csource_filename = source_file.get_csource_filename (); - } else { - var writer = new CCodeWriter (source_file.get_csource_filename ()); - if (!writer.open (context.version_header)) { - Report.error (null, "unable to open `%s' for writing".printf (writer.filename)); - return; - } - writer.close (); - } - - source_file.accept_children (this); - - if (context.report.get_errors () > 0) { - return; - } - } - - public void generate_enum_declaration (Enum en, CCodeFile decl_space) { - if (add_symbol_declaration (decl_space, en, get_ccode_name (en))) { - return; - } - - var cenum = new CCodeEnum (get_ccode_name (en)); - - foreach (EnumValue ev in en.get_values ()) { - if (ev.value == null) { - cenum.add_value (new CCodeEnumValue (get_ccode_name (ev))); - } else { - ev.value.emit (this); - cenum.add_value (new CCodeEnumValue (get_ccode_name (ev), get_cvalue (ev.value))); - } - } - - decl_space.add_type_definition (cenum); - decl_space.add_type_definition (new CCodeNewline ()); - } - - public override void visit_enum (Enum en) { - en.accept_children (this); - - generate_enum_declaration (en, cfile); - - if (!en.is_internal_symbol ()) { - generate_enum_declaration (en, header_file); - } - } - - public void generate_constant_declaration (Constant c, CCodeFile decl_space) { - if (add_symbol_declaration (decl_space, c, get_ccode_name (c))) { - return; - } - - if (!c.external) { - c.value.emit (this); - - if (c.value is InitializerList) { - var cdecl = new CCodeDeclaration (get_ccode_const_name (c.type_reference)); - var arr = ""; - if (c.type_reference is ArrayType) { - arr = "[]"; - } - cdecl.add_declarator (new CCodeVariableDeclarator ("%s%s".printf (get_ccode_name (c), arr), get_cvalue (c.value))); - cdecl.modifiers = CCodeModifiers.STATIC; - - decl_space.add_constant_declaration (cdecl); - } else { - var cdefine = new CCodeMacroReplacement.with_expression (get_ccode_name (c), get_cvalue (c.value)); - decl_space.add_type_member_declaration (cdefine); - } - } - } - - public override void visit_constant (Constant c) { - generate_constant_declaration (c, cfile); - - if (!c.is_internal_symbol ()) { - generate_constant_declaration (c, header_file); - } - } - - public void generate_field_declaration (Field f, CCodeFile decl_space) { - if (add_symbol_declaration (decl_space, f, get_ccode_name (f))) { - return; - } - - generate_type_declaration (f.variable_type, decl_space); - - string field_ctype = get_ccode_name (f.variable_type); - if (f.is_volatile) { - field_ctype = "volatile " + field_ctype; - } - - var cdecl = new CCodeDeclaration (field_ctype); - cdecl.add_declarator (new CCodeVariableDeclarator (get_ccode_name (f))); - if (f.is_internal_symbol ()) { - cdecl.modifiers = CCodeModifiers.STATIC; - } else { - cdecl.modifiers = CCodeModifiers.EXTERN; - } - - if (f.get_attribute ("ThreadLocal") != null) { - cdecl.modifiers |= CCodeModifiers.THREAD_LOCAL; - } - - decl_space.add_type_member_declaration (cdecl); - } - - public override void visit_field (Field f) { - if (f.binding == MemberBinding.STATIC) { - generate_field_declaration (f, cfile); - - if (!f.is_internal_symbol ()) { - generate_field_declaration (f, header_file); - } - - var var_decl = new CCodeVariableDeclarator (get_ccode_name (f)); - var_decl.initializer = default_value_for_type (f.variable_type, true); - - if (f.initializer != null) { - static_fields.add (f); - } - - string field_ctype = get_ccode_name (f.variable_type); - if (f.is_volatile) { - field_ctype = "volatile " + field_ctype; - } - - var var_def = new CCodeDeclaration (field_ctype); - var_def.add_declarator (var_decl); - if (!f.is_internal_symbol ()) { - var_def.modifiers = CCodeModifiers.EXTERN; - } else { - var_def.modifiers = CCodeModifiers.STATIC; - } - - if (f.get_attribute ("ThreadLocal") != null) { - var_def.modifiers |= CCodeModifiers.THREAD_LOCAL; - } - - cfile.add_type_member_declaration (var_def); - } - } - - public bool is_constant_ccode_expression (CCodeExpression cexpr) { - if (cexpr is CCodeConstant) { - return true; - } else if (cexpr is CCodeCastExpression) { - var ccast = (CCodeCastExpression) cexpr; - return is_constant_ccode_expression (ccast.inner); - } else if (cexpr is CCodeBinaryExpression) { - var cbinary = (CCodeBinaryExpression) cexpr; - return is_constant_ccode_expression (cbinary.left) && is_constant_ccode_expression (cbinary.right); - } - - var cparenthesized = (cexpr as CCodeParenthesizedExpression); - return (null != cparenthesized && is_constant_ccode_expression (cparenthesized.inner)); - } - - /** - * Returns whether the passed cexpr is a pure expression, i.e. an - * expression without side-effects. - */ - public bool is_pure_ccode_expression (CCodeExpression cexpr) { - if (cexpr is CCodeConstant || cexpr is CCodeIdentifier) { - return true; - } else if (cexpr is CCodeBinaryExpression) { - var cbinary = (CCodeBinaryExpression) cexpr; - return is_pure_ccode_expression (cbinary.left) && is_constant_ccode_expression (cbinary.right); - } else if (cexpr is CCodeUnaryExpression) { - var cunary = (CCodeUnaryExpression) cexpr; - switch (cunary.operator) { - case CCodeUnaryOperator.PREFIX_INCREMENT: - case CCodeUnaryOperator.PREFIX_DECREMENT: - case CCodeUnaryOperator.POSTFIX_INCREMENT: - case CCodeUnaryOperator.POSTFIX_DECREMENT: - return false; - default: - return is_pure_ccode_expression (cunary.inner); - } - } else if (cexpr is CCodeMemberAccess) { - var cma = (CCodeMemberAccess) cexpr; - return is_pure_ccode_expression (cma.inner); - } else if (cexpr is CCodeElementAccess) { - var cea = (CCodeElementAccess) cexpr; - return is_pure_ccode_expression (cea.container) && is_pure_ccode_expression (cea.index); - } else if (cexpr is CCodeCastExpression) { - var ccast = (CCodeCastExpression) cexpr; - return is_pure_ccode_expression (ccast.inner); - } else if (cexpr is CCodeParenthesizedExpression) { - var cparenthesized = (CCodeParenthesizedExpression) cexpr; - return is_pure_ccode_expression (cparenthesized.inner); - } - - return false; - } - - public override void visit_formal_parameter (Parameter p) { - } - - public override void visit_property (Property prop) { - if (prop.get_accessor != null) { - prop.get_accessor.accept (this); - } - if (prop.set_accessor != null) { - prop.set_accessor.accept (this); - } - } - - public void generate_type_declaration (DataType type, CCodeFile decl_space) { - if (type is ObjectType) { - var object_type = (ObjectType) type; - if (object_type.type_symbol is Class) { - generate_class_declaration ((Class) object_type.type_symbol, decl_space); - } else if (object_type.type_symbol is Interface) { - generate_interface_declaration ((Interface) object_type.type_symbol, decl_space); - } - } else if (type is DelegateType) { - var deleg_type = (DelegateType) type; - var d = deleg_type.delegate_symbol; - generate_delegate_declaration (d, decl_space); - } else if (type.data_type is Enum) { - var en = (Enum) type.data_type; - generate_enum_declaration (en, decl_space); - } else if (type is ValueType) { - var value_type = (ValueType) type; - generate_struct_declaration ((Struct) value_type.type_symbol, decl_space); - } else if (type is ArrayType) { - var array_type = (ArrayType) type; - generate_struct_declaration (array_struct, decl_space); - generate_type_declaration (array_type.element_type, decl_space); - } else if (type is PointerType) { - var pointer_type = (PointerType) type; - generate_type_declaration (pointer_type.base_type, decl_space); - } - - foreach (DataType type_arg in type.get_type_arguments ()) { - generate_type_declaration (type_arg, decl_space); - } - } - - public virtual void generate_struct_declaration (Struct st, CCodeFile decl_space) { - } - - public virtual void generate_delegate_declaration (Delegate d, CCodeFile decl_space) { - } - - public virtual void generate_cparameters (Method m, CCodeFile decl_space, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, CCodeFunctionCall? vcall = null) { - } - - public virtual void generate_property_accessor_declaration (PropertyAccessor acc, CCodeFile decl_space) { - } - - public int get_block_id (Block b) { - int result = block_map[b]; - if (result == 0) { - result = ++next_block_id; - block_map[b] = result; - } - return result; - } - - void capture_parameter (Parameter param, CCodeStruct data, int block_id, CCodeBlock free_block) { - generate_type_declaration (param.variable_type, cfile); - - var param_type = param.variable_type.copy (); - param_type.value_owned = true; - data.add_field (get_ccode_name (param_type), get_variable_cname (param.name)); - - // create copy if necessary as captured variables may need to be kept alive - CCodeExpression cparam = get_variable_cexpression (param.name); - if (requires_copy (param_type) && !param.variable_type.value_owned) { - var ma = new MemberAccess.simple (param.name); - ma.symbol_reference = param; - ma.value_type = param.variable_type.copy (); - // directly access parameters in ref expressions - param.captured = false; - cparam = get_ref_cexpression (param.variable_type, cparam, ma, param); - param.captured = true; - } - - ccode.add_assignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_variable_cname (param.name)), cparam); - - if (requires_destroy (param_type)) { - var ma = new MemberAccess.simple (param.name); - ma.symbol_reference = param; - ma.value_type = param_type.copy (); - free_block.add_statement (new CCodeExpressionStatement (get_unref_expression (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), get_variable_cname (param.name)), param.variable_type, ma))); - } - } - - public override void visit_block (Block b) { - emit_context.push_symbol (b); - - var local_vars = b.get_local_variables (); - - if (b.parent_node is Block || b.parent_node is SwitchStatement) { - ccode.open_block (); - } - - if (b.captured) { - var parent_block = next_closure_block (b.parent_symbol); - - int block_id = get_block_id (b); - string struct_name = "Block%dData".printf (block_id); - - var free_block = new CCodeBlock (); - - var data = new CCodeStruct ("_" + struct_name); - data.add_field ("DovaType*", "type"); - data.add_field ("int32_t", "_ref_count_"); - if (parent_block != null) { - int parent_block_id = get_block_id (parent_block); - - data.add_field ("Block%dData *".printf (parent_block_id), "_data%d_".printf (parent_block_id)); - - var unref_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_unref")); - unref_call.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id))); - free_block.add_statement (new CCodeExpressionStatement (unref_call)); - } else if ((current_method != null && current_method.binding == MemberBinding.INSTANCE) || - (current_property_accessor != null && current_property_accessor.prop.binding == MemberBinding.INSTANCE)) { - data.add_field ("%s *".printf (get_ccode_name (current_class)), "this"); - - var ma = new MemberAccess.simple ("this"); - ma.symbol_reference = current_class; - free_block.add_statement (new CCodeExpressionStatement (get_unref_expression (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "this"), new ObjectType (current_class), ma))); - } - foreach (var local in local_vars) { - if (local.captured) { - generate_type_declaration (local.variable_type, cfile); - - data.add_field (get_ccode_name (local.variable_type), get_variable_cname (local.name) + get_ccode_declarator_suffix (local.variable_type)); - } - } - // free in reverse order - for (int i = local_vars.size - 1; i >= 0; i--) { - var local = local_vars[i]; - if (local.captured) { - if (requires_destroy (local.variable_type)) { - var ma = new MemberAccess.simple (local.name); - ma.symbol_reference = local; - ma.value_type = local.variable_type.copy (); - free_block.add_statement (new CCodeExpressionStatement (get_unref_expression (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), get_variable_cname (local.name)), local.variable_type, ma))); - } - } - } - - var data_alloc = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_alloc")); - data_alloc.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_type_get".printf (block_id)))); - - var data_decl = new CCodeDeclaration (struct_name + "*"); - data_decl.add_declarator (new CCodeVariableDeclarator ("_data%d_".printf (block_id), data_alloc)); - ccode.add_statement (data_decl); - - if (parent_block != null) { - int parent_block_id = get_block_id (parent_block); - - var ref_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_ref")); - ref_call.add_argument (get_variable_cexpression ("_data%d_".printf (parent_block_id))); - - ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id)), ref_call))); - } else if ((current_method != null && current_method.binding == MemberBinding.INSTANCE) || - (current_property_accessor != null && current_property_accessor.prop.binding == MemberBinding.INSTANCE)) { - var ref_call = new CCodeFunctionCall (get_dup_func_expression (new ObjectType (current_class), b.source_reference)); - ref_call.add_argument (new CCodeIdentifier ("this")); - - ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "this"), ref_call))); - } - - if (b.parent_symbol is Method) { - var m = (Method) b.parent_symbol; - - // parameters are captured with the top-level block of the method - foreach (var param in m.get_parameters ()) { - if (param.captured) { - capture_parameter (param, data, block_id, free_block); - } - } - } else if (b.parent_symbol is PropertyAccessor) { - var acc = (PropertyAccessor) b.parent_symbol; - - if (!acc.readable && acc.value_parameter.captured) { - capture_parameter (acc.value_parameter, data, block_id, free_block); - } - } - - var typedef = new CCodeTypeDefinition ("struct _" + struct_name, new CCodeVariableDeclarator (struct_name)); - cfile.add_type_declaration (typedef); - cfile.add_type_definition (data); - - var data_free = new CCodeFunctionCall (new CCodeIdentifier ("free")); - data_free.add_argument (new CCodeIdentifier ("_data%d_".printf (block_id))); - free_block.add_statement (new CCodeExpressionStatement (data_free)); - - // create type_get/finalize functions - var type_get_fun = new CCodeFunction ("block%d_data_type_get".printf (block_id), "DovaType*"); - type_get_fun.modifiers = CCodeModifiers.STATIC; - cfile.add_function_declaration (type_get_fun); - type_get_fun.block = new CCodeBlock (); - - var cdecl = new CCodeDeclaration ("intptr_t"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_block%d_data_object_offset".printf (block_id), new CCodeConstant ("0"))); - cdecl.modifiers = CCodeModifiers.STATIC; - cfile.add_type_member_declaration (cdecl); - - cdecl = new CCodeDeclaration ("intptr_t"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_block%d_data_type_offset".printf (block_id), new CCodeConstant ("0"))); - cdecl.modifiers = CCodeModifiers.STATIC; - cfile.add_type_member_declaration (cdecl); - - cdecl = new CCodeDeclaration ("DovaType *"); - cdecl.add_declarator (new CCodeVariableDeclarator ("block%d_data_type".printf (block_id), new CCodeConstant ("NULL"))); - cdecl.modifiers = CCodeModifiers.STATIC; - cfile.add_type_member_declaration (cdecl); - - var type_init_block = new CCodeBlock (); - var alloc_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_alloc")); - alloc_call.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("dova_object_type_get"))); - alloc_call.add_argument (new CCodeConstant ("sizeof (%s)".printf (struct_name))); - alloc_call.add_argument (new CCodeConstant ("0")); - alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("block%d_data_type".printf (block_id)))); - alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_block%d_data_object_offset".printf (block_id)))); - alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_block%d_data_type_offset".printf (block_id)))); - type_init_block.add_statement (new CCodeExpressionStatement (alloc_call)); - var type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_type_init")); - type_init_call.add_argument (new CCodeIdentifier ("block%d_data_type".printf (block_id))); - type_init_block.add_statement (new CCodeExpressionStatement (type_init_call)); - type_get_fun.block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("block%d_data_type".printf (block_id))), type_init_block)); - type_get_fun.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("block%d_data_type".printf (block_id)))); - - cfile.add_function (type_get_fun); - - var unref_fun = new CCodeFunction ("block%d_data_finalize".printf (block_id), "void"); - unref_fun.add_parameter (new CCodeParameter ("_data%d_".printf (block_id), struct_name + "*")); - unref_fun.modifiers = CCodeModifiers.STATIC; - cfile.add_function_declaration (unref_fun); - unref_fun.block = free_block; - - cfile.add_function (unref_fun); - } - - foreach (Statement stmt in b.get_statements ()) { - stmt.emit (this); - } - - // free in reverse order - for (int i = local_vars.size - 1; i >= 0; i--) { - var local = local_vars[i]; - if (!local.floating && !local.captured && requires_destroy (local.variable_type)) { - var ma = new MemberAccess.simple (local.name); - ma.symbol_reference = local; - ccode.add_statement (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma))); - } - } - - if (b.parent_symbol is Method) { - var m = (Method) b.parent_symbol; - foreach (Parameter param in m.get_parameters ()) { - if (!param.captured && requires_destroy (param.variable_type) && param.direction == ParameterDirection.IN) { - var ma = new MemberAccess.simple (param.name); - ma.symbol_reference = param; - ccode.add_statement (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma))); - } - } - } - - if (b.captured) { - int block_id = get_block_id (b); - - var data_unref = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_unref")); - data_unref.add_argument (get_variable_cexpression ("_data%d_".printf (block_id))); - ccode.add_statement (new CCodeExpressionStatement (data_unref)); - } - - if (b.parent_node is Block || b.parent_node is SwitchStatement) { - ccode.close (); - } - - emit_context.pop_symbol (); - } - - public override void visit_declaration_statement (DeclarationStatement stmt) { - stmt.declaration.accept (this); - } - - public CCodeExpression get_variable_cexpression (string name) { - return new CCodeIdentifier (get_variable_cname (name)); - } - - public string get_variable_cname (string name) { - if (name[0] == '.') { - // compiler-internal variable - if (!variable_name_map.contains (name)) { - variable_name_map.set (name, "_tmp%d_".printf (next_temp_var_id)); - next_temp_var_id++; - } - return variable_name_map.get (name); - } else if (reserved_identifiers.contains (name)) { - return "_%s_".printf (name); - } else { - return name; - } - } - - public override void visit_local_variable (LocalVariable local) { - if (local.initializer != null) { - local.initializer.emit (this); - - visit_end_full_expression (local.initializer); - } - - generate_type_declaration (local.variable_type, cfile); - - CCodeExpression rhs = null; - if (local.initializer != null && get_cvalue (local.initializer) != null) { - rhs = get_cvalue (local.initializer); - } - - if (local.captured) { - if (local.initializer != null) { - ccode.add_assignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id ((Block) local.parent_symbol))), get_variable_cname (local.name)), rhs); - } - } else { - var cvar = new CCodeVariableDeclarator (get_variable_cname (local.name), rhs, get_ccode_declarator_suffix (local.variable_type)); - - var cdecl = new CCodeDeclaration (get_ccode_name (local.variable_type)); - cdecl.add_declarator (cvar); - ccode.add_statement (cdecl); - - // try to initialize uninitialized variables - // initialization not necessary for variables stored in closure - if (cvar.initializer == null) { - cvar.initializer = default_value_for_type (local.variable_type, true); - cvar.init0 = true; - } - } - - if (local.initializer != null && local.initializer.tree_can_fail) { - add_simple_check (local.initializer); - } - - local.active = true; - } - - public override void visit_initializer_list (InitializerList list) { - if (list.target_type.data_type is Struct) { - /* initializer is used as struct initializer */ - var st = (Struct) list.target_type.data_type; - - var clist = new CCodeInitializerList (); - - var field_it = st.get_fields ().iterator (); - foreach (Expression expr in list.get_initializers ()) { - Field field = null; - while (field == null) { - field_it.next (); - field = field_it.get (); - if (field.binding != MemberBinding.INSTANCE) { - // we only initialize instance fields - field = null; - } - } - - var cexpr = get_cvalue (expr); - - string ctype = field.get_ctype (); - if (ctype != null) { - cexpr = new CCodeCastExpression (cexpr, ctype); - } - - clist.append (cexpr); - } - - set_cvalue (list, clist); - } else { - var clist = new CCodeInitializerList (); - foreach (Expression expr in list.get_initializers ()) { - clist.append (get_cvalue (expr)); - } - set_cvalue (list, clist); - } - } - - public override LocalVariable create_local (DataType type) { - var result = get_temp_variable (type, type.value_owned); - emit_temp_var (result); - return result; - } - - public LocalVariable get_temp_variable (DataType type, bool value_owned = true, CodeNode? node_reference = null) { - var var_type = type.copy (); - var_type.value_owned = value_owned; - var local = new LocalVariable (var_type, "_tmp%d_".printf (next_temp_var_id)); - - if (node_reference != null) { - local.source_reference = node_reference.source_reference; - } - - next_temp_var_id++; - - return local; - } - - bool is_in_generic_type (DataType type) { - if (type.type_parameter.parent_symbol is TypeSymbol - && (current_method == null || current_method.binding == MemberBinding.INSTANCE)) { - return true; - } else { - return false; - } - } - - public CCodeExpression get_type_private_from_type (ObjectTypeSymbol type_symbol, CCodeExpression type_expression) { - if (type_symbol is Class) { - // class - return new CCodeCastExpression (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeCastExpression (type_expression, "char *"), new CCodeIdentifier ("_%s_type_offset".printf (CCodeBaseModule.get_ccode_lower_case_name (type_symbol)))), "%sTypePrivate *".printf (get_ccode_name (type_symbol))); - } else { - // interface - var get_interface = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_interface")); - get_interface.add_argument (type_expression); - get_interface.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (type_symbol)))); - return new CCodeCastExpression (get_interface, "%sTypePrivate *".printf (CCodeBaseModule.get_ccode_name (type_symbol))); - } - } - - public CCodeExpression get_type_id_expression (DataType type, bool is_chainup = false) { - if (type is GenericType) { - string var_name = "%s_type".printf (type.type_parameter.name.down ()); - if (is_in_generic_type (type) && !is_chainup) { - return new CCodeMemberAccess.pointer (get_type_private_from_type ((ObjectTypeSymbol) type.type_parameter.parent_symbol, new CCodeMemberAccess.pointer (new CCodeIdentifier ("this"), "type")), var_name); - } else { - return new CCodeIdentifier (var_name); - } - } else { - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (CCodeBaseModule.get_ccode_lower_case_name (type.data_type)))); - var object_type_symbol = type.data_type as ObjectTypeSymbol; - if (object_type_symbol != null) { - for (int i = 0; i < object_type_symbol.get_type_parameters ().size; i++) { - if (type.get_type_arguments ().size == 0) { - ccall.add_argument (new CCodeConstant ("NULL")); - } else { - ccall.add_argument (get_type_id_expression (type.get_type_arguments ().get (i))); - } - } - } - return ccall; - } - } - - public virtual CCodeExpression? get_dup_func_expression (DataType type, SourceReference? source_reference, bool is_chainup = false) { - if (type.data_type != null) { - string dup_function = ""; - if (is_reference_counting (type.data_type)) { - dup_function = get_ccode_ref_function (type.data_type); - } else if (type is ValueType) { - dup_function = get_ccode_dup_function (type.data_type); - if (dup_function == null) { - dup_function = ""; - } - } - - return new CCodeIdentifier (dup_function); - } else if (type.type_parameter != null) { - return null; - } else if (type is ArrayType) { - return new CCodeIdentifier ("dova_object_ref"); - } else if (type is DelegateType) { - return new CCodeIdentifier ("dova_object_ref"); - } else if (type is PointerType) { - var pointer_type = (PointerType) type; - return get_dup_func_expression (pointer_type.base_type, source_reference); - } else { - return new CCodeConstant ("NULL"); - } - } - - public CCodeExpression? get_destroy_func_expression (DataType type, bool is_chainup = false) { - if (type.data_type != null) { - string unref_function; - if (type is ReferenceType) { - if (is_reference_counting (type.data_type)) { - unref_function = get_ccode_unref_function ((ObjectTypeSymbol) type.data_type); - } else { - unref_function = get_ccode_free_function (type.data_type); - } - } else { - if (type.nullable) { - unref_function = get_ccode_free_function (type.data_type); - if (unref_function == null) { - unref_function = "free"; - } - } else { - var st = (Struct) type.data_type; - unref_function = get_ccode_copy_function (st); - } - } - if (unref_function == null) { - return new CCodeConstant ("NULL"); - } - return new CCodeIdentifier (unref_function); - } else if (type.type_parameter != null && current_type_symbol is Class) { - // FIXME ask type for dup/ref function - return new CCodeIdentifier ("dova_object_unref"); - } else if (type is ArrayType) { - return new CCodeIdentifier ("dova_object_unref"); - } else if (type is DelegateType) { - return new CCodeIdentifier ("dova_object_unref"); - } else if (type is PointerType) { - return new CCodeIdentifier ("free"); - } else { - return new CCodeConstant ("NULL"); - } - } - - public CCodeExpression get_unref_expression (CCodeExpression cvar, DataType type, Expression? expr = null) { - return destroy_value (new DovaValue (type, cvar)); - } - - public CCodeExpression destroy_value (TargetValue value) { - var type = value.value_type; - var cvar = get_cvalue_ (value); - - var ccall = new CCodeFunctionCall (get_destroy_func_expression (type)); - - if (type is ValueType && !type.nullable) { - // normal value type, no null check - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cvar)); - ccall.add_argument (new CCodeConstant ("0")); - ccall.add_argument (new CCodeConstant ("NULL")); - ccall.add_argument (new CCodeConstant ("0")); - - return ccall; - } - - /* (foo == NULL ? NULL : foo = (unref (foo), NULL)) */ - - /* can be simplified to - * foo = (unref (foo), NULL) - * if foo is of static type non-null - */ - - var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, cvar, new CCodeConstant ("NULL")); - if (type.type_parameter != null) { - if (!(current_type_symbol is Class) || current_class.is_compact) { - return new CCodeConstant ("NULL"); - } - - // unref functions are optional for type parameters - var cunrefisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, get_destroy_func_expression (type), new CCodeConstant ("NULL")); - cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.OR, cisnull, cunrefisnull); - } - - ccall.add_argument (cvar); - - /* set freed references to NULL to prevent further use */ - var ccomma = new CCodeCommaExpression (); - - ccomma.append_expression (ccall); - ccomma.append_expression (new CCodeConstant ("NULL")); - - var cassign = new CCodeAssignment (cvar, ccomma); - - return new CCodeConditionalExpression (cisnull, new CCodeConstant ("NULL"), cassign); - } - - public override void visit_end_full_expression (Expression expr) { - /* expr is a full expression, i.e. an initializer, the - * expression in an expression statement, the controlling - * expression in if, while, for, or foreach statements - * - * we unref temporary variables at the end of a full - * expression - */ - - if (((List) temp_ref_vars).size == 0) { - /* nothing to do without temporary variables */ - return; - } - - var expr_type = expr.value_type; - if (expr.target_type != null) { - expr_type = expr.target_type; - } - - var full_expr_var = get_temp_variable (expr_type, true, expr); - emit_temp_var (full_expr_var); - - var expr_list = new CCodeCommaExpression (); - expr_list.append_expression (new CCodeAssignment (get_variable_cexpression (full_expr_var.name), get_cvalue (expr))); - - foreach (LocalVariable local in temp_ref_vars) { - var ma = new MemberAccess.simple (local.name); - ma.symbol_reference = local; - expr_list.append_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)); - } - - expr_list.append_expression (get_variable_cexpression (full_expr_var.name)); - - set_cvalue (expr, expr_list); - - temp_ref_vars.clear (); - } - - public void emit_temp_var (LocalVariable local) { - var cdecl = new CCodeDeclaration (get_ccode_name (local.variable_type)); - - var vardecl = new CCodeVariableDeclarator (local.name, null, get_ccode_declarator_suffix (local.variable_type)); - cdecl.add_declarator (vardecl); - - var st = local.variable_type.data_type as Struct; - var array_type = local.variable_type as ArrayType; - - if (local.name.has_prefix ("*")) { - // do not dereference unintialized variable - // initialization is not needed for these special - // pointer temp variables - // used to avoid side-effects in assignments - } else if (local.variable_type is GenericType) { - var value_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_value_size")); - value_size.add_argument (get_type_id_expression (local.variable_type)); - - var alloca_call = new CCodeFunctionCall (new CCodeIdentifier ("alloca")); - alloca_call.add_argument (value_size); - - var memset_call = new CCodeFunctionCall (new CCodeIdentifier ("memset")); - memset_call.add_argument (alloca_call); - memset_call.add_argument (new CCodeConstant ("0")); - memset_call.add_argument (value_size); - - vardecl.initializer = memset_call; - vardecl.init0 = true; - } else if (!local.variable_type.nullable && - (st != null && st.get_fields ().size > 0) || - array_type != null) { - // 0-initialize struct with struct initializer { 0 } - // necessary as they will be passed by reference - var clist = new CCodeInitializerList (); - clist.append (new CCodeConstant ("0")); - - vardecl.initializer = clist; - vardecl.init0 = true; - } else if (local.variable_type.is_reference_type_or_type_parameter () || - local.variable_type.nullable) { - vardecl.initializer = new CCodeConstant ("NULL"); - vardecl.init0 = true; - } - - ccode.add_statement (cdecl); - } - - public override void visit_expression_statement (ExpressionStatement stmt) { - if (stmt.expression.error) { - stmt.error = true; - return; - } - - if (get_cvalue (stmt.expression) != null) { - ccode.add_expression (get_cvalue (stmt.expression)); - } - /* free temporary objects and handle errors */ - - foreach (LocalVariable local in temp_ref_vars) { - var ma = new MemberAccess.simple (local.name); - ma.symbol_reference = local; - ma.value_type = local.variable_type.copy (); - ccode.add_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)); - } - - if (stmt.tree_can_fail && stmt.expression.tree_can_fail) { - // simple case, no node breakdown necessary - add_simple_check (stmt.expression); - } - - temp_ref_vars.clear (); - } - - public virtual void append_local_free (Symbol sym, bool stop_at_loop = false, CodeNode? stop_at = null) { - var b = (Block) sym; - - var local_vars = b.get_local_variables (); - // free in reverse order - for (int i = local_vars.size - 1; i >= 0; i--) { - var local = local_vars[i]; - if (local.active && !local.floating && !local.captured && requires_destroy (local.variable_type)) { - var ma = new MemberAccess.simple (local.name); - ma.symbol_reference = local; - ccode.add_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)); - } - } - - if (b.captured) { - int block_id = get_block_id (b); - - var data_unref = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_unref")); - data_unref.add_argument (get_variable_cexpression ("_data%d_".printf (block_id))); - ccode.add_expression (data_unref); - } - - if (stop_at_loop) { - if (b.parent_node is Loop || - b.parent_node is ForeachStatement || - b.parent_node is SwitchStatement) { - return; - } - } - - if (b.parent_node == stop_at) { - return; - } - - if (sym.parent_symbol is Block) { - append_local_free (sym.parent_symbol, stop_at_loop, stop_at); - } else if (sym.parent_symbol is Method) { - append_param_free ((Method) sym.parent_symbol); - } - } - - private void append_param_free (Method m) { - foreach (Parameter param in m.get_parameters ()) { - if (requires_destroy (param.variable_type) && param.direction == ParameterDirection.IN) { - var ma = new MemberAccess.simple (param.name); - ma.symbol_reference = param; - ccode.add_expression (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma)); - } - } - } - - public override void visit_return_statement (ReturnStatement stmt) { - // free local variables - append_local_free (current_symbol); - - ccode.add_return ((current_return_type is VoidType) ? null : new CCodeIdentifier ("result")); - } - - public override void visit_delete_statement (DeleteStatement stmt) { - var pointer_type = stmt.expression.value_type as PointerType; - var array_type = stmt.expression.value_type as ArrayType; - - if (pointer_type != null) { - DataType type = pointer_type; - if (pointer_type.base_type.data_type != null && pointer_type.base_type.data_type.is_reference_type ()) { - type = pointer_type.base_type; - } - - var ccall = new CCodeFunctionCall (get_destroy_func_expression (type)); - ccall.add_argument (get_cvalue (stmt.expression)); - ccode.add_expression (ccall); - } else if (array_type != null) { - // TODO free elements - var free_call = new CCodeFunctionCall (new CCodeIdentifier ("free")); - free_call.add_argument (new CCodeMemberAccess (get_cvalue (stmt.expression), "data")); - ccode.add_expression (free_call); - - ccode.add_assignment (new CCodeMemberAccess (get_cvalue (stmt.expression), "data"), new CCodeConstant ("NULL")); - ccode.add_assignment (new CCodeMemberAccess (get_cvalue (stmt.expression), "length"), new CCodeConstant ("0")); - } else { - assert_not_reached (); - } - } - - public override void visit_expression (Expression expr) { - if (get_cvalue (expr) != null && !expr.lvalue) { - // memory management, implicit casts, and boxing/unboxing - set_cvalue (expr, transform_expression (get_cvalue (expr), expr.value_type, expr.target_type, expr)); - } - } - - public override void visit_boolean_literal (BooleanLiteral expr) { - set_cvalue (expr, new CCodeConstant (expr.value ? "true" : "false")); - } - - public override void visit_character_literal (CharacterLiteral expr) { - if (expr.get_char () >= 0x20 && expr.get_char () < 0x80) { - set_cvalue (expr, new CCodeConstant (expr.value)); - } else { - set_cvalue (expr, new CCodeConstant ("%uU".printf (expr.get_char ()))); - } - } - - public override void visit_integer_literal (IntegerLiteral expr) { - set_cvalue (expr, new CCodeConstant (expr.value)); - } - - public override void visit_real_literal (RealLiteral expr) { - string c_literal = expr.value; - if (c_literal.has_suffix ("d") || c_literal.has_suffix ("D")) { - // there is no suffix for double in C - c_literal = c_literal.substring (0, c_literal.length - 1); - } - if (!("." in c_literal || "e" in c_literal || "E" in c_literal)) { - // C requires period or exponent part for floating constants - if ("f" in c_literal || "F" in c_literal) { - c_literal = c_literal.substring (0, c_literal.length - 1) + ".f"; - } else { - c_literal += "."; - } - } - set_cvalue (expr, new CCodeConstant (c_literal)); - } - - public override void visit_string_literal (StringLiteral expr) { - // FIXME handle escaped characters in scanner/parser and escape them here again for C - var cliteral = new CCodeConstant ("\"\\0\" " + expr.value); - - var cbinary = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, cliteral, new CCodeConstant ("1")); - set_cvalue (expr, new CCodeCastExpression (cbinary, "string_t")); - } - - public override void visit_null_literal (NullLiteral expr) { - set_cvalue (expr, new CCodeConstant ("NULL")); - } - - public override void visit_base_access (BaseAccess expr) { - generate_type_declaration (expr.value_type, cfile); - set_cvalue (expr, new CCodeCastExpression (new CCodeIdentifier ("this"), get_ccode_name (expr.value_type))); - } - - public override void visit_postfix_expression (PostfixExpression expr) { - MemberAccess ma = find_property_access (expr.inner); - if (ma != null) { - // property postfix expression - var prop = (Property) ma.symbol_reference; - - // assign current value to temp variable - var temp_decl = get_temp_variable (prop.property_type, true, expr); - emit_temp_var (temp_decl); - ccode.add_assignment (get_variable_cexpression (temp_decl.name), get_cvalue (expr.inner)); - - // increment/decrement property - var op = expr.increment ? CCodeBinaryOperator.PLUS : CCodeBinaryOperator.MINUS; - var cexpr = new CCodeBinaryExpression (op, get_variable_cexpression (temp_decl.name), new CCodeConstant ("1")); - store_property (prop, ma.inner, new DovaValue (expr.value_type, cexpr)); - - // return previous value - set_cvalue (expr, new CCodeIdentifier (temp_decl.name)); - return; - } - - var op = expr.increment ? CCodeUnaryOperator.POSTFIX_INCREMENT : CCodeUnaryOperator.POSTFIX_DECREMENT; - - set_cvalue (expr, new CCodeUnaryExpression (op, get_cvalue (expr.inner))); - } - - private MemberAccess? find_property_access (Expression expr) { - if (!(expr is MemberAccess)) { - return null; - } - - var ma = (MemberAccess) expr; - if (ma.symbol_reference is Property) { - return ma; - } - - return null; - } - - public bool requires_copy (DataType type) { - if (!type.is_disposable ()) { - return false; - } - - var cl = type.data_type as Class; - if (cl != null && is_reference_counting (cl) - && get_ccode_ref_function (cl) == "") { - // empty ref_function => no ref necessary - return false; - } - - if (type.type_parameter != null) { - return false; - } - - return true; - } - - public bool requires_destroy (DataType type) { - if (!type.is_disposable ()) { - return false; - } - - var array_type = type as ArrayType; - if (array_type != null && array_type.inline_allocated) { - return requires_destroy (array_type.element_type); - } - - var cl = type.data_type as Class; - if (cl != null && is_reference_counting (cl) - && get_ccode_unref_function (cl) == "") { - // empty unref_function => no unref necessary - return false; - } - - if (type.type_parameter != null) { - return false; - } - - return true; - } - - bool is_ref_function_void (DataType type) { - var cl = type.data_type as Class; - if (cl != null && get_ccode_ref_function_void (cl)) { - return true; - } else { - return false; - } - } - - public virtual CCodeExpression? get_ref_cexpression (DataType expression_type, CCodeExpression cexpr, Expression? expr, CodeNode node) { - if (expression_type is ValueType && !expression_type.nullable) { - // normal value type, no null check - // (copy (&temp, 0, &expr, 0), temp) - - var decl = get_temp_variable (expression_type, false, node); - emit_temp_var (decl); - - var ctemp = get_variable_cexpression (decl.name); - - var vt = (ValueType) expression_type; - var st = (Struct) vt.type_symbol; - var copy_call = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_copy_function (st))); - copy_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp)); - copy_call.add_argument (new CCodeConstant ("0")); - copy_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr)); - copy_call.add_argument (new CCodeConstant ("0")); - - var ccomma = new CCodeCommaExpression (); - - ccomma.append_expression (copy_call); - ccomma.append_expression (ctemp); - - return ccomma; - } - - /* (temp = expr, temp == NULL ? NULL : ref (temp)) - * - * can be simplified to - * ref (expr) - * if static type of expr is non-null - */ - - var dupexpr = get_dup_func_expression (expression_type, node.source_reference); - - if (dupexpr == null) { - node.error = true; - return null; - } - - var ccall = new CCodeFunctionCall (dupexpr); - - if (expr != null && expr.is_non_null () - && !is_ref_function_void (expression_type)) { - // expression is non-null - ccall.add_argument (get_cvalue (expr)); - - return ccall; - } else { - var decl = get_temp_variable (expression_type, false, node); - emit_temp_var (decl); - - var ctemp = get_variable_cexpression (decl.name); - - var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ctemp, new CCodeConstant ("NULL")); - if (expression_type.type_parameter != null) { - // dup functions are optional for type parameters - var cdupisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, get_dup_func_expression (expression_type, node.source_reference), new CCodeConstant ("NULL")); - cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.OR, cisnull, cdupisnull); - } - - ccall.add_argument (ctemp); - - var ccomma = new CCodeCommaExpression (); - ccomma.append_expression (new CCodeAssignment (ctemp, cexpr)); - - var cifnull = new CCodeConstant ("NULL"); - ccomma.append_expression (new CCodeConditionalExpression (cisnull, cifnull, ccall)); - - // repeat temp variable at the end of the comma expression - // if the ref function returns void - if (is_ref_function_void (expression_type)) { - ccomma.append_expression (ctemp); - } - - return ccomma; - } - } - - public virtual void generate_class_declaration (Class cl, CCodeFile decl_space) { - if (add_symbol_declaration (decl_space, cl, get_ccode_name (cl))) { - return; - } - } - - public virtual void generate_interface_declaration (Interface iface, CCodeFile decl_space) { - } - - public virtual void generate_method_declaration (Method m, CCodeFile decl_space) { - } - - public void add_generic_type_arguments (CCodeFunctionCall ccall, List type_args, CodeNode expr, bool is_chainup = false) { - foreach (var type_arg in type_args) { - ccall.add_argument (get_type_id_expression (type_arg, is_chainup)); - } - } - - public override void visit_object_creation_expression (ObjectCreationExpression expr) { - CCodeExpression instance = null; - CCodeExpression creation_expr = null; - - var st = expr.type_reference.data_type as Struct; - - bool struct_by_ref = false; - if (st != null && !st.is_boolean_type () && !st.is_integer_type () && !st.is_floating_type ()) { - struct_by_ref = true; - } - - if (struct_by_ref || expr.get_object_initializer ().size > 0) { - // value-type initialization or object creation expression with object initializer - var temp_decl = get_temp_variable (expr.type_reference, false, expr); - emit_temp_var (temp_decl); - - instance = get_variable_cexpression (get_variable_cname (temp_decl.name)); - } - - if (expr.symbol_reference == null) { - // no creation method - if (expr.type_reference.data_type is Struct) { - var creation_call = new CCodeFunctionCall (new CCodeIdentifier ("memset")); - creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance)); - creation_call.add_argument (new CCodeConstant ("0")); - creation_call.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (get_ccode_name (expr.type_reference)))); - - creation_expr = creation_call; - } - } else if (expr.symbol_reference is Method) { - // use creation method - var m = (Method) expr.symbol_reference; - var params = m.get_parameters (); - CCodeFunctionCall creation_call; - - generate_method_declaration (m, cfile); - - var cl = expr.type_reference.data_type as Class; - - if (!CCodeBaseModule.get_ccode_has_new_function (m)) { - // use construct function directly - creation_call = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_real_name (m))); - creation_call.add_argument (new CCodeIdentifier (CCodeBaseModule.get_ccode_type_id (cl))); - } else { - creation_call = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_name (m))); - } - - if (struct_by_ref && !(get_ccode_instance_pos (m) < 0)) { - creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance)); - } - - generate_type_declaration (expr.type_reference, cfile); - - if (cl != null && !cl.is_compact) { - add_generic_type_arguments (creation_call, expr.type_reference.get_type_arguments (), expr); - } - - bool ellipsis = false; - - int i = 1; - Iterator params_it = params.iterator (); - foreach (Expression arg in expr.get_argument_list ()) { - CCodeExpression cexpr = get_cvalue (arg); - Parameter param = null; - if (params_it.next ()) { - param = params_it.get (); - ellipsis = param.ellipsis; - if (!ellipsis) { - cexpr = handle_struct_argument (param, arg, cexpr); - } - } - - creation_call.add_argument (cexpr); - - i++; - } - while (params_it.next ()) { - var param = params_it.get (); - - if (param.ellipsis) { - ellipsis = true; - break; - } - - if (param.initializer == null) { - Report.error (expr.source_reference, "no default expression for argument %d".printf (i)); - return; - } - - /* evaluate default expression here as the code - * generator might not have visited the formal - * parameter yet */ - param.initializer.emit (this); - - creation_call.add_argument (get_cvalue (param.initializer)); - i++; - } - - if (struct_by_ref && get_ccode_instance_pos (m) < 0) { - // instance parameter is at the end in a struct creation method - creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance)); - } - - if (ellipsis) { - /* ensure variable argument list ends with NULL - * except when using printf-style arguments */ - if (!m.printf_format && !m.scanf_format && get_ccode_sentinel (m) != "") { - creation_call.add_argument (new CCodeConstant (get_ccode_sentinel (m))); - } - } - - creation_expr = creation_call; - - // cast the return value of the creation method back to the intended type if - // it requested a special C return type - if (get_custom_creturn_type (m) != null) { - creation_expr = new CCodeCastExpression (creation_expr, get_ccode_name (expr.type_reference)); - } - } else { - assert (false); - } - - if (instance != null) { - if (expr.type_reference.data_type is Struct) { - ccode.add_expression (creation_expr); - } else { - ccode.add_assignment (instance, creation_expr); - } - - foreach (MemberInitializer init in expr.get_object_initializer ()) { - if (init.symbol_reference is Field) { - var f = (Field) init.symbol_reference; - var instance_target_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol); - var typed_inst = transform_expression (instance, expr.type_reference, instance_target_type); - CCodeExpression lhs; - if (expr.type_reference.data_type is Struct) { - lhs = new CCodeMemberAccess (typed_inst, get_ccode_name (f)); - } else { - lhs = new CCodeMemberAccess.pointer (typed_inst, get_ccode_name (f)); - } - ccode.add_assignment (lhs, get_cvalue (init.initializer)); - } else if (init.symbol_reference is Property) { - var inst_ma = new MemberAccess.simple ("new"); - inst_ma.value_type = expr.type_reference; - set_cvalue (inst_ma, instance); - store_property ((Property) init.symbol_reference, inst_ma, init.initializer.target_value); - } - } - - creation_expr = instance; - } - - if (creation_expr != null) { - var temp_var = get_temp_variable (expr.value_type); - var temp_ref = get_variable_cexpression (temp_var.name); - - emit_temp_var (temp_var); - - ccode.add_assignment (temp_ref, creation_expr); - set_cvalue (expr, temp_ref); - } - } - - public CCodeExpression? handle_struct_argument (Parameter param, Expression arg, CCodeExpression? cexpr) { - if (arg.formal_target_type is GenericType && !(arg.target_type is GenericType)) { - // we already use a reference for arguments of ref and out parameters - if (param.direction == ParameterDirection.IN) { - var unary = cexpr as CCodeUnaryExpression; - if (unary != null && unary.operator == CCodeUnaryOperator.POINTER_INDIRECTION) { - // *expr => expr - return unary.inner; - } else if (cexpr is CCodeIdentifier || cexpr is CCodeMemberAccess) { - return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr); - } else { - // if cexpr is e.g. a function call, we can't take the address of the expression - // (tmp = expr, &tmp) - var ccomma = new CCodeCommaExpression (); - - var temp_var = get_temp_variable (arg.target_type); - emit_temp_var (temp_var); - ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), cexpr)); - ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_var.name))); - - return ccomma; - } - } - } - - return cexpr; - } - - public override void visit_sizeof_expression (SizeofExpression expr) { - var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof")); - csizeof.add_argument (new CCodeIdentifier (get_ccode_name (expr.type_reference))); - set_cvalue (expr, csizeof); - } - - public override void visit_typeof_expression (TypeofExpression expr) { - set_cvalue (expr, get_type_id_expression (expr.type_reference)); - } - - public override void visit_unary_expression (UnaryExpression expr) { - CCodeUnaryOperator op; - if (expr.operator == UnaryOperator.PLUS) { - op = CCodeUnaryOperator.PLUS; - } else if (expr.operator == UnaryOperator.MINUS) { - op = CCodeUnaryOperator.MINUS; - } else if (expr.operator == UnaryOperator.LOGICAL_NEGATION) { - op = CCodeUnaryOperator.LOGICAL_NEGATION; - } else if (expr.operator == UnaryOperator.BITWISE_COMPLEMENT) { - op = CCodeUnaryOperator.BITWISE_COMPLEMENT; - } else if (expr.operator == UnaryOperator.INCREMENT) { - op = CCodeUnaryOperator.PREFIX_INCREMENT; - } else if (expr.operator == UnaryOperator.DECREMENT) { - op = CCodeUnaryOperator.PREFIX_DECREMENT; - } else if (expr.operator == UnaryOperator.REF) { - op = CCodeUnaryOperator.ADDRESS_OF; - } else if (expr.operator == UnaryOperator.OUT) { - op = CCodeUnaryOperator.ADDRESS_OF; - } else { - assert_not_reached (); - } - set_cvalue (expr, new CCodeUnaryExpression (op, get_cvalue (expr.inner))); - } - - public override void visit_cast_expression (CastExpression expr) { - if (expr.is_silent_cast) { - if (expr.inner.value_type is ObjectType) { - var ccomma = new CCodeCommaExpression (); - var temp_decl = get_temp_variable (expr.inner.value_type, true, expr); - - emit_temp_var (temp_decl); - - var ctemp = get_variable_cexpression (temp_decl.name); - var cinit = new CCodeAssignment (ctemp, get_cvalue (expr.inner)); - var ccheck = create_type_check (ctemp, expr.type_reference); - var ccast = new CCodeCastExpression (ctemp, get_ccode_name (expr.type_reference)); - var cnull = new CCodeConstant ("NULL"); - - ccomma.append_expression (cinit); - ccomma.append_expression (new CCodeConditionalExpression (ccheck, ccast, cnull)); - - set_cvalue (expr, ccomma); - } else { - expr.error = true; - Report.error (expr.source_reference, "Operation not supported for this type"); - } - return; - } - - if (expr.type_reference.data_type != null && expr.type_reference.data_type.get_full_name () == "Dova.Value") { - // box value - var temp_decl = get_temp_variable (expr.inner.value_type, true, expr); - emit_temp_var (temp_decl); - var cvar = get_variable_cexpression (temp_decl.name); - - var ccomma = new CCodeCommaExpression (); - ccomma.append_expression (new CCodeAssignment (cvar, get_cvalue (expr.inner))); - - var to_any = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_value_to_any")); - to_any.add_argument (get_type_id_expression (expr.inner.value_type)); - to_any.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cvar)); - to_any.add_argument (new CCodeConstant ("0")); - ccomma.append_expression (to_any); - - set_cvalue (expr, ccomma); - return; - } else if (expr.inner.value_type.data_type != null && expr.inner.value_type.data_type.get_full_name () == "Dova.Value") { - // unbox value - var temp_decl = get_temp_variable (expr.type_reference, true, expr); - emit_temp_var (temp_decl); - var cvar = get_variable_cexpression (temp_decl.name); - - var ccomma = new CCodeCommaExpression (); - - var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof")); - sizeof_call.add_argument (new CCodeIdentifier (get_ccode_name (expr.type_reference))); - - var to_any = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_value_from_any")); - to_any.add_argument (get_type_id_expression (expr.type_reference)); - to_any.add_argument (get_cvalue (expr.inner)); - to_any.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cvar)); - to_any.add_argument (new CCodeConstant ("0")); - ccomma.append_expression (to_any); - - ccomma.append_expression (cvar); - - set_cvalue (expr, ccomma); - return; - } - - if (expr.inner.value_type is ArrayType && expr.type_reference is PointerType) { - var array_type = (ArrayType) expr.inner.value_type; - if (!array_type.fixed_length) { - set_cvalue (expr, new CCodeMemberAccess (get_cvalue (expr.inner), "data")); - return; - } - } - - generate_type_declaration (expr.type_reference, cfile); - - if (expr.inner.value_type is GenericType && !(expr.type_reference is GenericType)) { - // generic types use an extra pointer, dereference that pointer - set_cvalue (expr, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeCastExpression (get_cvalue (expr.inner), get_ccode_name (expr.type_reference) + "*"))); - } else { - set_cvalue (expr, new CCodeCastExpression (get_cvalue (expr.inner), get_ccode_name (expr.type_reference))); - } - } - - public override void visit_pointer_indirection (PointerIndirection expr) { - set_cvalue (expr, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_cvalue (expr.inner))); - } - - public override void visit_addressof_expression (AddressofExpression expr) { - set_cvalue (expr, new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_cvalue (expr.inner))); - } - - public override void visit_reference_transfer_expression (ReferenceTransferExpression expr) { - /* (tmp = var, var = null, tmp) */ - var ccomma = new CCodeCommaExpression (); - var temp_decl = get_temp_variable (expr.value_type, true, expr); - emit_temp_var (temp_decl); - var cvar = get_variable_cexpression (temp_decl.name); - - ccomma.append_expression (new CCodeAssignment (cvar, get_cvalue (expr.inner))); - ccomma.append_expression (new CCodeAssignment (get_cvalue (expr.inner), new CCodeConstant ("NULL"))); - ccomma.append_expression (cvar); - set_cvalue (expr, ccomma); - } - - public override void visit_binary_expression (BinaryExpression expr) { - var cleft = get_cvalue (expr.left); - var cright = get_cvalue (expr.right); - - CCodeBinaryOperator op; - if (expr.operator == BinaryOperator.PLUS) { - op = CCodeBinaryOperator.PLUS; - } else if (expr.operator == BinaryOperator.MINUS) { - op = CCodeBinaryOperator.MINUS; - } else if (expr.operator == BinaryOperator.MUL) { - op = CCodeBinaryOperator.MUL; - } else if (expr.operator == BinaryOperator.DIV) { - op = CCodeBinaryOperator.DIV; - } else if (expr.operator == BinaryOperator.MOD) { - op = CCodeBinaryOperator.MOD; - } else if (expr.operator == BinaryOperator.SHIFT_LEFT) { - op = CCodeBinaryOperator.SHIFT_LEFT; - } else if (expr.operator == BinaryOperator.SHIFT_RIGHT) { - op = CCodeBinaryOperator.SHIFT_RIGHT; - } else if (expr.operator == BinaryOperator.LESS_THAN) { - op = CCodeBinaryOperator.LESS_THAN; - } else if (expr.operator == BinaryOperator.GREATER_THAN) { - op = CCodeBinaryOperator.GREATER_THAN; - } else if (expr.operator == BinaryOperator.LESS_THAN_OR_EQUAL) { - op = CCodeBinaryOperator.LESS_THAN_OR_EQUAL; - } else if (expr.operator == BinaryOperator.GREATER_THAN_OR_EQUAL) { - op = CCodeBinaryOperator.GREATER_THAN_OR_EQUAL; - } else if (expr.operator == BinaryOperator.EQUALITY) { - op = CCodeBinaryOperator.EQUALITY; - } else if (expr.operator == BinaryOperator.INEQUALITY) { - op = CCodeBinaryOperator.INEQUALITY; - } else if (expr.operator == BinaryOperator.BITWISE_AND) { - op = CCodeBinaryOperator.BITWISE_AND; - } else if (expr.operator == BinaryOperator.BITWISE_OR) { - op = CCodeBinaryOperator.BITWISE_OR; - } else if (expr.operator == BinaryOperator.BITWISE_XOR) { - op = CCodeBinaryOperator.BITWISE_XOR; - } else if (expr.operator == BinaryOperator.AND) { - op = CCodeBinaryOperator.AND; - } else if (expr.operator == BinaryOperator.OR) { - op = CCodeBinaryOperator.OR; - } else if (expr.operator == BinaryOperator.IN) { - set_cvalue (expr, new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeBinaryExpression (CCodeBinaryOperator.BITWISE_AND, cright, cleft), cleft)); - return; - } else { - assert_not_reached (); - } - - if (expr.operator == BinaryOperator.EQUALITY || - expr.operator == BinaryOperator.INEQUALITY) { - var left_type_as_struct = expr.left.value_type.data_type as Struct; - var right_type_as_struct = expr.right.value_type.data_type as Struct; - - if (expr.left.value_type.data_type is Class && !((Class) expr.left.value_type.data_type).is_compact && - expr.right.value_type.data_type is Class && !((Class) expr.right.value_type.data_type).is_compact) { - var left_cl = (Class) expr.left.value_type.data_type; - var right_cl = (Class) expr.right.value_type.data_type; - - if (left_cl != right_cl) { - if (left_cl.is_subtype_of (right_cl)) { - cleft = generate_instance_cast (cleft, right_cl); - } else if (right_cl.is_subtype_of (left_cl)) { - cright = generate_instance_cast (cright, left_cl); - } - } - } else if (left_type_as_struct != null && right_type_as_struct != null) { - // FIXME generate and use compare/equal function for real structs - if (expr.left.value_type.nullable && expr.right.value_type.nullable) { - // FIXME also compare contents, not just address - } else if (expr.left.value_type.nullable) { - // FIXME check left value is not null - cleft = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, cleft); - } else if (expr.right.value_type.nullable) { - // FIXME check right value is not null - cright = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, cright); - } - } - } - - set_cvalue (expr, new CCodeBinaryExpression (op, cleft, cright)); - } - - CCodeExpression? create_type_check (CCodeNode ccodenode, DataType type) { - var ccheck = new CCodeFunctionCall (new CCodeIdentifier ("any_is_a")); - ccheck.add_argument ((CCodeExpression) ccodenode); - ccheck.add_argument (get_type_id_expression (type)); - return ccheck; - } - - public override void visit_type_check (TypeCheck expr) { - generate_type_declaration (expr.type_reference, cfile); - - set_cvalue (expr, create_type_check (get_cvalue (expr.expression), expr.type_reference)); - if (get_cvalue (expr) is CCodeInvalidExpression) { - Report.error (expr.source_reference, "type check expressions not supported for compact classes, structs, and enums"); - } - } - - public override void visit_lambda_expression (LambdaExpression l) { - l.accept_children (this); - - set_cvalue (l, new CCodeIdentifier (get_ccode_name (l.method))); - } - - // manage memory and implicit casts - public CCodeExpression transform_expression (CCodeExpression source_cexpr, DataType? expression_type, DataType? target_type, Expression? expr = null) { - var cexpr = source_cexpr; - if (expression_type == null) { - return cexpr; - } - - - if (expression_type.value_owned - && (target_type == null || !target_type.value_owned)) { - // value leaked, destroy it - var pointer_type = target_type as PointerType; - if (pointer_type != null && !(pointer_type.base_type is VoidType)) { - // manual memory management for non-void pointers - // treat void* special to not leak memory with void* method parameters - } else if (requires_destroy (expression_type)) { - var decl = get_temp_variable (expression_type, true, expression_type); - emit_temp_var (decl); - temp_ref_vars.insert (0, decl); - cexpr = new CCodeAssignment (get_variable_cexpression (decl.name), cexpr); - } - } - - if (target_type == null) { - // value will be destroyed, no need for implicit casts - return cexpr; - } - - cexpr = get_implicit_cast_expression (cexpr, expression_type, target_type, expr); - - if (target_type.value_owned && !expression_type.value_owned) { - // need to copy value - if (requires_copy (target_type) && !(expression_type is NullType)) { - CodeNode node = expr; - if (node == null) { - node = expression_type; - } - cexpr = get_ref_cexpression (target_type, cexpr, expr, node); - } - } - - return cexpr; - } - - public virtual CCodeExpression get_implicit_cast_expression (CCodeExpression source_cexpr, DataType? expression_type, DataType? target_type, Expression? expr = null) { - var cexpr = source_cexpr; - - if (expression_type.data_type != null && expression_type.data_type == target_type.data_type) { - // same type, no cast required - return cexpr; - } - - if (expression_type is NullType) { - if (target_type is ArrayType) { - var array = new CCodeFunctionCall (new CCodeIdentifier ("dova_array")); - array.add_argument (new CCodeConstant ("NULL")); - array.add_argument (new CCodeConstant ("0")); - return array; - } - - // null literal, no cast required when not converting to generic type pointer - return cexpr; - } - - if (expression_type is ArrayType && target_type is PointerType) { - var array_type = (ArrayType) expression_type; - if (!array_type.inline_allocated) { - return new CCodeMemberAccess (cexpr, "data"); - } - } - - if (expression_type is ArrayType && target_type is ArrayType) { - var source_array_type = (ArrayType) expression_type; - var target_array_type = (ArrayType) target_type; - if (source_array_type.inline_allocated && !target_array_type.inline_allocated) { - var array = new CCodeFunctionCall (new CCodeIdentifier ("dova_array")); - array.add_argument (cexpr); - - var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof")); - csizeof.add_argument (cexpr); - var csizeofelement = new CCodeFunctionCall (new CCodeIdentifier ("sizeof")); - csizeofelement.add_argument (new CCodeElementAccess (cexpr, new CCodeConstant ("0"))); - array.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.DIV, csizeof, csizeofelement)); - - return array; - } - } - - generate_type_declaration (target_type, cfile); - - if (target_type is DelegateType && expression_type is MethodType) { - var deleg_type = (DelegateType) target_type; - var method_type = (MethodType) expression_type; - CCodeExpression delegate_target; - if (expr is LambdaExpression) { - var lambda = (LambdaExpression) expr; - if (lambda.method.closure) { - int block_id = get_block_id (current_closure_block); - delegate_target = get_variable_cexpression ("_data%d_".printf (block_id)); - } else if (get_this_type () != null) { - delegate_target = new CCodeIdentifier ("this"); - } else { - delegate_target = new CCodeConstant ("NULL"); - } - } else { - if (method_type.method_symbol.binding == MemberBinding.INSTANCE) { - var ma = (MemberAccess) expr; - delegate_target = (CCodeExpression) get_ccodenode (ma.inner); - } else { - delegate_target = new CCodeConstant ("NULL"); - } - } - - var d = deleg_type.delegate_symbol; - - string wrapper_name = "_wrapper%d_".printf (next_wrapper_id++); - var wrapper = new CCodeFunction (wrapper_name); - wrapper.modifiers = CCodeModifiers.STATIC; - var call = new CCodeFunctionCall (source_cexpr); - - if (method_type.method_symbol.binding == MemberBinding.INSTANCE) { - wrapper.add_parameter (new CCodeParameter ("this", "void *")); - call.add_argument (new CCodeIdentifier ("this")); - } - - var method_param_iter = method_type.method_symbol.get_parameters ().iterator (); - foreach (Parameter param in d.get_parameters ()) { - method_param_iter.next (); - var method_param = method_param_iter.get (); - string ctype = get_ccode_name (param.variable_type); - if (param.variable_type is GenericType && !(method_param.variable_type is GenericType)) { - ctype = get_ccode_name (method_param.variable_type) + "*"; - call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (param.name))); - } else if (!(param.variable_type is GenericType) && method_param.variable_type is GenericType) { - call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name))); - } else { - call.add_argument (new CCodeIdentifier (param.name)); - } - - wrapper.add_parameter (new CCodeParameter (param.name, ctype)); - } - - wrapper.block = new CCodeBlock (); - if (d.return_type is VoidType) { - wrapper.block.add_statement (new CCodeExpressionStatement (call)); - } else { - var method_return_type = method_type.method_symbol.return_type; - if (d.return_type is GenericType && !(method_return_type is GenericType)) { - wrapper.add_parameter (new CCodeParameter ("result", get_ccode_name (method_return_type) + "*")); - wrapper.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result")), call))); - } else if (!(d.return_type is GenericType) && method_return_type is GenericType) { - wrapper.return_type = get_ccode_name (d.return_type); - var cdecl = new CCodeDeclaration (get_ccode_name (d.return_type)); - cdecl.add_declarator (new CCodeVariableDeclarator ("result")); - call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result"))); - wrapper.block.add_statement (new CCodeExpressionStatement (call)); - wrapper.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result"))); - } else if (d.return_type is GenericType) { - wrapper.add_parameter (new CCodeParameter ("result", "void *")); - wrapper.block.add_statement (new CCodeExpressionStatement (call)); - } else { - wrapper.return_type = get_ccode_name (d.return_type); - wrapper.block.add_statement (new CCodeReturnStatement (call)); - } - } - - cfile.add_function (wrapper); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_new".printf (get_ccode_lower_case_name (deleg_type.delegate_symbol)))); - ccall.add_argument (delegate_target); - ccall.add_argument (new CCodeIdentifier (wrapper_name)); - return ccall; - } - - var cl = target_type.data_type as Class; - var iface = target_type.data_type as Interface; - if (context.checking && (iface != null || (cl != null && !cl.is_compact))) { - // checked cast for strict subtypes of GTypeInstance - return generate_instance_cast (cexpr, target_type.data_type); - } else if (target_type.data_type != null && get_ccode_name (expression_type) != get_ccode_name (target_type)) { - var st = target_type.data_type as Struct; - if (target_type.data_type.is_reference_type () || (st != null && st.is_simple_type ())) { - // don't cast non-simple structs - return new CCodeCastExpression (cexpr, get_ccode_name (target_type)); - } else { - return cexpr; - } - } else { - return cexpr; - } - } - - public void store_property (Property prop, Expression? instance, TargetValue value) { - string set_func; - - var base_property = prop; - if (prop.base_property != null) { - base_property = prop.base_property; - } else if (prop.base_interface_property != null) { - base_property = prop.base_interface_property; - } - - generate_property_accessor_declaration (base_property.set_accessor, cfile); - set_func = get_ccode_name (base_property.set_accessor); - - if (!prop.external && prop.external_package) { - // internal VAPI properties - // only add them once per source file - if (add_generated_external_symbol (prop)) { - visit_property (prop); - } - } - - var ccall = new CCodeFunctionCall (new CCodeIdentifier (set_func)); - - if (prop.binding == MemberBinding.INSTANCE) { - /* target instance is first argument */ - ccall.add_argument ((CCodeExpression) get_ccodenode (instance)); - } - - ccall.add_argument (get_cvalue_ (value)); - - ccode.add_expression (ccall); - } - - public bool add_generated_external_symbol (Symbol external_symbol) { - return generated_external_symbols.add (external_symbol); - } - - public static DataType get_data_type_for_symbol (TypeSymbol sym) { - DataType type = null; - - if (sym is Class) { - type = new ObjectType ((Class) sym); - } else if (sym is Interface) { - type = new ObjectType ((Interface) sym); - } else if (sym is Struct) { - var st = (Struct) sym; - if (st.is_boolean_type ()) { - type = new BooleanType (st); - } else if (st.is_integer_type ()) { - type = new IntegerType (st); - } else if (st.is_floating_type ()) { - type = new FloatingType (st); - } else { - type = new StructValueType (st); - } - } else if (sym is Enum) { - type = new EnumValueType ((Enum) sym); - } else { - Report.error (null, "internal error: `%s' is not a supported type".printf (sym.get_full_name ())); - return new InvalidType (); - } - - return type; - } - - public CCodeExpression? default_value_for_type (DataType type, bool initializer_expression) { - var st = type.data_type as Struct; - var array_type = type as ArrayType; - if (type is GenericType) { - var value_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_value_size")); - value_size.add_argument (get_type_id_expression (type)); - - var alloca_call = new CCodeFunctionCall (new CCodeIdentifier ("alloca")); - alloca_call.add_argument (value_size); - - var memset_call = new CCodeFunctionCall (new CCodeIdentifier ("memset")); - memset_call.add_argument (alloca_call); - memset_call.add_argument (new CCodeConstant ("0")); - memset_call.add_argument (value_size); - - return memset_call; - } else if (initializer_expression && !type.nullable && - ((st != null && st.get_fields ().size > 0) || - array_type != null)) { - // 0-initialize struct with struct initializer { 0 } - // only allowed as initializer expression in C - var clist = new CCodeInitializerList (); - clist.append (new CCodeConstant ("0")); - return clist; - } else if ((type.data_type != null && type.data_type.is_reference_type ()) - || type.nullable - || type is PointerType || type is DelegateType) { - return new CCodeConstant ("NULL"); - } else if (type.data_type != null && get_ccode_default_value (type.data_type) != "") { - return new CCodeConstant (get_ccode_default_value (type.data_type)); - } - return null; - } - - public CCodeExpression? get_ccodenode (Expression node) { - if (get_cvalue (node) == null) { - node.emit (this); - } - return get_cvalue (node); - } - - public string get_ccode_name (CodeNode node) { - return CCodeBaseModule.get_ccode_name (node); - } - - public string get_ccode_const_name (CodeNode node) { - return CCodeBaseModule.get_ccode_const_name (node); - } - - public string get_ccode_copy_function (TypeSymbol node) { - return CCodeBaseModule.get_ccode_copy_function (node); - } - - public string get_ccode_dup_function (TypeSymbol node) { - return CCodeBaseModule.get_ccode_dup_function (node); - } - - public string get_ccode_ref_function (TypeSymbol node) { - return CCodeBaseModule.get_ccode_ref_function (node); - } - - public string get_ccode_unref_function (ObjectTypeSymbol node) { - return CCodeBaseModule.get_ccode_unref_function (node); - } - - public string get_ccode_free_function (TypeSymbol node) { - return CCodeBaseModule.get_ccode_free_function (node); - } - - public bool is_reference_counting (TypeSymbol node) { - return CCodeBaseModule.is_reference_counting (node); - } - - public bool get_ccode_ref_function_void (Class node) { - return CCodeBaseModule.get_ccode_ref_function_void (node); - } - - public string get_ccode_default_value (TypeSymbol node) { - return CCodeBaseModule.get_ccode_default_value (node); - } - - public string get_ccode_real_name (Method node) { - return CCodeBaseModule.get_ccode_real_name (node); - } - - public string get_ccode_lower_case_name (CodeNode node, string? infix = null) { - return CCodeBaseModule.get_ccode_lower_case_name (node, infix); - } - - public string get_ccode_upper_case_name (Symbol node, string? infix = null) { - return CCodeBaseModule.get_ccode_upper_case_name (node, infix); - } - - public string get_ccode_lower_case_prefix (Symbol node) { - return CCodeBaseModule.get_ccode_lower_case_prefix (node); - } - - public double get_ccode_instance_pos (CodeNode node) { - return CCodeBaseModule.get_ccode_instance_pos (node); - } - - public string get_ccode_vfunc_name (Method node) { - return CCodeBaseModule.get_ccode_vfunc_name (node); - } - - public string get_ccode_sentinel (Method m) { - return CCodeBaseModule.get_ccode_sentinel (m); - } - - public string get_ccode_declarator_suffix (DataType type) { - return CCodeBaseModule.get_ccode_declarator_suffix (type); - } - - public DataType? get_this_type () { - if (current_method != null && current_method.binding == MemberBinding.INSTANCE) { - return current_method.this_parameter.variable_type; - } else if (current_property_accessor != null && current_property_accessor.prop.binding == MemberBinding.INSTANCE) { - return current_property_accessor.prop.this_parameter.variable_type; - } - return null; - } - - public CCodeExpression generate_instance_cast (CCodeExpression expr, TypeSymbol type) { - return new CCodeCastExpression (expr, get_ccode_name (type) + "*"); - } - - public virtual string? get_custom_creturn_type (Method m) { - return null; - } - - public virtual bool method_has_wrapper (Method method) { - return false; - } - - public virtual void add_simple_check (CodeNode node, bool always_fails = false) { - } - - public CCodeExpression? get_cvalue (Expression expr) { - if (expr.target_value == null) { - return null; - } - var dova_value = (DovaValue) expr.target_value; - return dova_value.cvalue; - } - - public CCodeExpression? get_cvalue_ (TargetValue value) { - var dova_value = (DovaValue) value; - return dova_value.cvalue; - } - - public void set_cvalue (Expression expr, CCodeExpression? cvalue) { - var dova_value = (DovaValue) expr.target_value; - if (dova_value == null) { - dova_value = new DovaValue (expr.value_type); - expr.target_value = dova_value; - } - dova_value.cvalue = cvalue; - } -} - -public class Vala.DovaValue : TargetValue { - public CCodeExpression cvalue; - - public DovaValue (DataType? value_type = null, CCodeExpression? cvalue = null) { - base (value_type); - this.cvalue = cvalue; - } -} diff --git a/codegen/valadovacontrolflowmodule.vala b/codegen/valadovacontrolflowmodule.vala deleted file mode 100644 index 115ac7db7..000000000 --- a/codegen/valadovacontrolflowmodule.vala +++ /dev/null @@ -1,80 +0,0 @@ -/* valadovacontrolflowmodule.vala - * - * Copyright (C) 2006-2010 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.1 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 - */ - -public abstract class Vala.DovaControlFlowModule : DovaMethodModule { - public override void visit_if_statement (IfStatement stmt) { - ccode.open_if (get_cvalue (stmt.condition)); - - stmt.true_statement.emit (this); - - if (stmt.false_statement != null) { - ccode.add_else (); - stmt.false_statement.emit (this); - } - - ccode.close (); - } - - public override void visit_switch_statement (SwitchStatement stmt) { - ccode.open_switch (get_cvalue (stmt.expression)); - - foreach (SwitchSection section in stmt.get_sections ()) { - if (section.has_default_label ()) { - ccode.add_default (); - } - section.emit (this); - } - - ccode.close (); - } - - public override void visit_switch_label (SwitchLabel label) { - if (label.expression != null) { - label.expression.emit (this); - - visit_end_full_expression (label.expression); - - ccode.add_case (get_cvalue (label.expression)); - } - } - - public override void visit_loop (Loop stmt) { - ccode.open_while (new CCodeConstant ("true")); - - stmt.body.emit (this); - - ccode.close (); - } - - public override void visit_break_statement (BreakStatement stmt) { - append_local_free (current_symbol, true); - - ccode.add_break (); - } - - public override void visit_continue_statement (ContinueStatement stmt) { - append_local_free (current_symbol, true); - - ccode.add_continue (); - } -} - diff --git a/codegen/valadovadelegatemodule.vala b/codegen/valadovadelegatemodule.vala deleted file mode 100644 index 5cb043910..000000000 --- a/codegen/valadovadelegatemodule.vala +++ /dev/null @@ -1,221 +0,0 @@ -/* valadovadelegatemodule.vala - * - * Copyright (C) 2006-2010 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.1 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 - * Raffaele Sandrini - */ - -/** - * The link between a delegate and generated code. - */ -public class Vala.DovaDelegateModule : DovaValueModule { - public override void generate_delegate_declaration (Delegate d, CCodeFile decl_space) { - if (add_symbol_declaration (decl_space, d, get_ccode_name (d))) { - return; - } - - decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (get_ccode_name (d)), new CCodeVariableDeclarator (get_ccode_name (d)))); - - generate_class_declaration (type_class, decl_space); - generate_method_declaration ((Method) object_class.scope.lookup ("ref"), decl_space); - generate_method_declaration ((Method) object_class.scope.lookup ("unref"), decl_space); - - var type_fun = new CCodeFunction ("%s_type_get".printf (get_ccode_lower_case_name (d)), "DovaType *"); - if (d.is_internal_symbol ()) { - type_fun.modifiers = CCodeModifiers.STATIC; - } - decl_space.add_function_declaration (type_fun); - - var type_init_fun = new CCodeFunction ("%s_type_init".printf (get_ccode_lower_case_name (d))); - if (d.is_internal_symbol ()) { - type_init_fun.modifiers = CCodeModifiers.STATIC; - } - type_init_fun.add_parameter (new CCodeParameter ("type", "DovaType *")); - decl_space.add_function_declaration (type_init_fun); - - generate_type_declaration (d.return_type, decl_space); - - var function = generate_new_function (d, decl_space); - function.block = null; - decl_space.add_function_declaration (function); - - function = generate_invoke_function (d, decl_space); - function.block = null; - decl_space.add_function_declaration (function); - } - - CCodeFunction generate_new_function (Delegate d, CCodeFile decl_space) { - var function = new CCodeFunction ("%s_new".printf (get_ccode_lower_case_name (d)), "%s*".printf (get_ccode_name (d))); - if (d.is_internal_symbol ()) { - function.modifiers |= CCodeModifiers.STATIC; - } - - function.add_parameter (new CCodeParameter ("target", "DovaObject *")); - function.add_parameter (new CCodeParameter ("(*method) (void)", "void")); - - function.block = new CCodeBlock (); - - var alloc_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_alloc")); - alloc_call.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (d))))); - - var cdecl = new CCodeDeclaration ("%s*".printf (get_ccode_name (d))); - cdecl.add_declarator (new CCodeVariableDeclarator ("this", alloc_call)); - function.block.add_statement (cdecl); - - var init_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_delegate_init")); - init_call.add_argument (new CCodeIdentifier ("this")); - init_call.add_argument (new CCodeIdentifier ("target")); - function.block.add_statement (new CCodeExpressionStatement (init_call)); - - var priv = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (get_ccode_upper_case_name (d)))); - priv.add_argument (new CCodeIdentifier ("this")); - var assignment = new CCodeAssignment (new CCodeMemberAccess.pointer (priv, "method"), new CCodeIdentifier ("method")); - function.block.add_statement (new CCodeExpressionStatement (assignment)); - - function.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("this"))); - - return function; - } - - CCodeFunction generate_invoke_function (Delegate d, CCodeFile decl_space) { - var function = new CCodeFunction ("%s_invoke".printf (get_ccode_lower_case_name (d))); - - if (d.is_internal_symbol ()) { - function.modifiers |= CCodeModifiers.STATIC; - } - - function.add_parameter (new CCodeParameter ("this", "%s*".printf (get_ccode_name (d)))); - - string param_list = ""; - - foreach (Parameter param in d.get_parameters ()) { - generate_type_declaration (param.variable_type, decl_space); - - function.add_parameter (new CCodeParameter (param.name, get_ccode_name (param.variable_type))); - - if (param_list != "") { - param_list += ", "; - } - param_list += get_ccode_name (param.variable_type); - } - - if (d.return_type is GenericType) { - function.add_parameter (new CCodeParameter ("result", "void *")); - - if (param_list != "") { - param_list += ", "; - } - param_list += "void *"; - } else { - function.return_type = get_ccode_name (d.return_type); - } - - function.block = new CCodeBlock (); - - var get_target = new CCodeFunctionCall (new CCodeIdentifier ("dova_delegate_get_target")); - get_target.add_argument (new CCodeIdentifier ("this")); - - var cdecl = new CCodeDeclaration ("DovaObject*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("target", get_target)); - function.block.add_statement (cdecl); - - var priv = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (get_ccode_upper_case_name (d)))); - priv.add_argument (new CCodeIdentifier ("this")); - - string instance_param_list = "(DovaObject *"; - if (param_list != "") { - instance_param_list += ","; - instance_param_list += param_list; - } - instance_param_list += ")"; - - var instance_block = new CCodeBlock (); - var instance_call = new CCodeFunctionCall (new CCodeCastExpression (new CCodeMemberAccess.pointer (priv, "method"), "%s (*) %s".printf (function.return_type, instance_param_list))); - - instance_call.add_argument (new CCodeIdentifier ("target")); - - string static_param_list = "("; - if (param_list != "") { - static_param_list += param_list; - } else { - static_param_list += "void"; - } - static_param_list += ")"; - - var static_block = new CCodeBlock (); - var static_call = new CCodeFunctionCall (new CCodeCastExpression (new CCodeMemberAccess.pointer (priv, "method"), "%s (*) %s".printf (function.return_type, static_param_list))); - - foreach (Parameter param in d.get_parameters ()) { - instance_call.add_argument (new CCodeIdentifier (param.name)); - static_call.add_argument (new CCodeIdentifier (param.name)); - } - - if (d.return_type is VoidType) { - instance_block.add_statement (new CCodeExpressionStatement (instance_call)); - static_block.add_statement (new CCodeExpressionStatement (static_call)); - } else if (d.return_type is GenericType) { - instance_call.add_argument (new CCodeIdentifier ("result")); - static_call.add_argument (new CCodeIdentifier ("result")); - instance_block.add_statement (new CCodeExpressionStatement (instance_call)); - static_block.add_statement (new CCodeExpressionStatement (static_call)); - } else { - instance_block.add_statement (new CCodeReturnStatement (instance_call)); - static_block.add_statement (new CCodeReturnStatement (static_call)); - } - - function.block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("target"), instance_block, static_block)); - - return function; - } - - public override void visit_delegate (Delegate d) { - d.accept_children (this); - - generate_delegate_declaration (d, cfile); - - if (!d.is_internal_symbol ()) { - generate_delegate_declaration (d, header_file); - } - - generate_type_get_function (d, delegate_class); - - var instance_priv_struct = new CCodeStruct ("_%sPrivate".printf (get_ccode_name (d))); - - instance_priv_struct.add_field ("void", "(*method) (void)"); - - cfile.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (instance_priv_struct.name), new CCodeVariableDeclarator ("%sPrivate".printf (get_ccode_name (d))))); - cfile.add_type_definition (instance_priv_struct); - - string macro = "((%sPrivate *) (((char *) o) + _%s_object_offset))".printf (get_ccode_name (d), get_ccode_lower_case_name (d)); - cfile.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (get_ccode_upper_case_name (d, null)), macro)); - - var cdecl = new CCodeDeclaration ("intptr_t"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_%s_object_offset".printf (get_ccode_lower_case_name (d)), new CCodeConstant ("0"))); - cdecl.modifiers = CCodeModifiers.STATIC; - cfile.add_type_member_declaration (cdecl); - - cdecl = new CCodeDeclaration ("intptr_t"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_%s_type_offset".printf (get_ccode_lower_case_name (d)), new CCodeConstant ("0"))); - cdecl.modifiers = CCodeModifiers.STATIC; - cfile.add_type_member_declaration (cdecl); - - cfile.add_function (generate_new_function (d, cfile)); - cfile.add_function (generate_invoke_function (d, cfile)); - } -} diff --git a/codegen/valadovaerrormodule.vala b/codegen/valadovaerrormodule.vala deleted file mode 100644 index 68f7a860f..000000000 --- a/codegen/valadovaerrormodule.vala +++ /dev/null @@ -1,277 +0,0 @@ -/* valadovaerrormodule.vala - * - * Copyright (C) 2008-2010 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.1 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 - * Thijs Vermeir - */ - -public class Vala.DovaErrorModule : DovaDelegateModule { - private int current_try_id = 0; - private int next_try_id = 0; - private bool is_in_catch = false; - - public override void visit_throw_statement (ThrowStatement stmt) { - ccode.add_assignment (new CCodeIdentifier ("dova_error"), get_cvalue (stmt.error_expression)); - - add_simple_check (stmt, true); - } - - public void return_with_exception () { - // propagate error - // nothing to do - - // free local variables - append_local_free (current_symbol, false); - - if (current_method is CreationMethod && current_method.parent_symbol is Class) { - var cl = current_method.parent_symbol as Class; - var unref_call = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_unref_function (cl))); - unref_call.add_argument (new CCodeIdentifier ("this")); - ccode.add_expression (unref_call); - ccode.add_return (); - } else if (current_return_type is VoidType) { - ccode.add_return (); - } else { - ccode.add_return (default_value_for_type (current_return_type, false)); - } - } - - void uncaught_error_statement () { - // free local variables - append_local_free (current_symbol, false); - - // TODO log uncaught error as critical warning - - if (current_method is CreationMethod) { - ccode.add_return (); - } else if (current_return_type is VoidType) { - ccode.add_return (); - } else if (current_return_type != null) { - ccode.add_return (default_value_for_type (current_return_type, false)); - } - } - - bool in_finally_block (CodeNode node) { - var current_node = node; - while (current_node != null) { - var try_stmt = current_node.parent_node as TryStatement; - if (try_stmt != null && try_stmt.finally_body == current_node) { - return true; - } - current_node = current_node.parent_node; - } - return false; - } - - public override void add_simple_check (CodeNode node, bool always_fails = false) { - if (always_fails) { - // inner_error is always set, avoid unnecessary if statement - // eliminates C warnings - } else { - var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("dova_error"), new CCodeConstant ("NULL")); - ccode.open_if (ccond); - } - - if (current_try != null) { - // surrounding try found - - // free local variables - append_local_free (current_symbol, false, current_try); - - var error_types = new ArrayList (); - foreach (DataType node_error_type in node.get_error_types ()) { - error_types.add (node_error_type); - } - - bool has_general_catch_clause = false; - - if (!is_in_catch) { - var handled_error_types = new ArrayList (); - foreach (CatchClause clause in current_try.get_catch_clauses ()) { - // keep track of unhandled error types - foreach (DataType node_error_type in error_types) { - if (clause.error_type == null || node_error_type.compatible (clause.error_type)) { - handled_error_types.add (node_error_type); - } - } - foreach (DataType handled_error_type in handled_error_types) { - error_types.remove (handled_error_type); - } - handled_error_types.clear (); - - if (clause.error_type.equals (new ObjectType (error_class))) { - // general catch clause, this should be the last one - has_general_catch_clause = true; - ccode.add_goto (clause.clabel_name); - break; - } else { - var catch_type = clause.error_type as ObjectType; - - var type_check = new CCodeFunctionCall (new CCodeIdentifier ("any_is_a")); - type_check.add_argument (new CCodeIdentifier ("dova_error")); - type_check.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (catch_type.type_symbol))))); - - ccode.open_if (type_check); - - // go to catch clause if error domain matches - ccode.add_goto (clause.clabel_name); - ccode.close (); - } - } - } - - if (has_general_catch_clause) { - // every possible error is already caught - // as there is a general catch clause - // no need to do anything else - } else if (error_types.size > 0) { - // go to finally clause if no catch clause matches - // and there are still unhandled error types - ccode.add_goto ("__finally%d".printf (current_try_id)); - } else if (in_finally_block (node)) { - // do not check unexpected errors happening within finally blocks - // as jump out of finally block is not supported - } else { - assert_not_reached (); - } - } else if (current_method != null && current_method.get_error_types ().size > 0) { - // current method can fail, propagate error - CCodeExpression ccond = null; - - foreach (DataType error_type in current_method.get_error_types ()) { - // If Dova.Error is allowed we propagate everything - if (error_type.equals (new ObjectType (error_class))) { - ccond = null; - break; - } - - // Check the allowed error domains to propagate - var type_check = new CCodeFunctionCall (new CCodeIdentifier ("any_is_a")); - type_check.add_argument (new CCodeIdentifier ("dova_error")); - type_check.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (error_class))))); - if (ccond == null) { - ccond = type_check; - } else { - ccond = new CCodeBinaryExpression (CCodeBinaryOperator.OR, ccond, type_check); - } - } - - if (ccond == null) { - return_with_exception (); - } else { - ccode.open_if (ccond); - return_with_exception (); - ccode.add_else (); - uncaught_error_statement (); - ccode.close (); - } - } else { - uncaught_error_statement (); - } - - if (!always_fails) { - ccode.close (); - } - } - - public override void visit_try_statement (TryStatement stmt) { - int this_try_id = next_try_id++; - - var old_try = current_try; - var old_try_id = current_try_id; - var old_is_in_catch = is_in_catch; - current_try = stmt; - current_try_id = this_try_id; - is_in_catch = true; - - foreach (CatchClause clause in stmt.get_catch_clauses ()) { - clause.clabel_name = "__catch%d_%s".printf (this_try_id, get_ccode_lower_case_name (clause.error_type)); - } - - is_in_catch = false; - stmt.body.emit (this); - is_in_catch = true; - - foreach (CatchClause clause in stmt.get_catch_clauses ()) { - ccode.add_goto ("__finally%d".printf (this_try_id)); - clause.emit (this); - } - - current_try = old_try; - current_try_id = old_try_id; - is_in_catch = old_is_in_catch; - - ccode.add_label ("__finally%d".printf (this_try_id)); - if (stmt.finally_body != null) { - stmt.finally_body.emit (this); - } - - // check for errors not handled by this try statement - // may be handled by outer try statements or propagated - add_simple_check (stmt, !stmt.after_try_block_reachable); - } - - public override void visit_catch_clause (CatchClause clause) { - generate_type_declaration (clause.error_type, cfile); - - ccode.add_label (clause.clabel_name); - - ccode.open_block (); - - string variable_name; - if (clause.variable_name != null) { - variable_name = get_variable_cname (clause.variable_name); - } else { - variable_name = "__err"; - } - - if (clause.variable_name != null) { - var cdecl = new CCodeDeclaration (get_ccode_name (clause.error_type)); - cdecl.add_declarator (new CCodeVariableDeclarator (variable_name, new CCodeIdentifier ("dova_error"))); - ccode.add_statement (cdecl); - } else { - // error object is not used within catch statement, clear it - var cclear = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_unref")); - cclear.add_argument (new CCodeIdentifier ("dova_error")); - ccode.add_statement (new CCodeExpressionStatement (cclear)); - } - ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("dova_error"), new CCodeConstant ("NULL")))); - - clause.body.emit (this); - - ccode.close (); - } - - public override void append_local_free (Symbol sym, bool stop_at_loop = false, CodeNode? stop_at = null) { - var finally_block = (Block) null; - if (sym.parent_node is TryStatement) { - finally_block = (sym.parent_node as TryStatement).finally_body; - } else if (sym.parent_node is CatchClause) { - finally_block = (sym.parent_node.parent_node as TryStatement).finally_body; - } - - if (finally_block != null) { - finally_block.emit (this); - } - - base.append_local_free (sym, stop_at_loop, stop_at); - } -} - -// vim:sw=8 noet diff --git a/codegen/valadovamemberaccessmodule.vala b/codegen/valadovamemberaccessmodule.vala deleted file mode 100644 index 44760f922..000000000 --- a/codegen/valadovamemberaccessmodule.vala +++ /dev/null @@ -1,307 +0,0 @@ -/* valadovamemberaccessmodule.vala - * - * Copyright (C) 2006-2011 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.1 of the License, or (at your option) any later version. - - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: - * Jürg Billeter - */ - -using GLib; - -public abstract class Vala.DovaMemberAccessModule : DovaControlFlowModule { - public override void visit_member_access (MemberAccess expr) { - CCodeExpression pub_inst = null; - DataType base_type = null; - - if (expr.inner != null) { - pub_inst = get_cvalue (expr.inner); - - if (expr.inner.value_type != null) { - base_type = expr.inner.value_type; - } - } - - if (expr.symbol_reference is Method) { - var m = (Method) expr.symbol_reference; - - if (!(m is DynamicMethod)) { - generate_method_declaration (m, cfile); - - if (!m.external && m.external_package) { - // internal VAPI methods - // only add them once per source file - if (add_generated_external_symbol (m)) { - visit_method (m); - } - } - } - - if (expr.inner is BaseAccess) { - if (m.base_method != null) { - var base_class = (Class) m.base_method.parent_symbol; - - set_cvalue (expr, new CCodeIdentifier ("%s_base_%s".printf (get_ccode_lower_case_name (base_class, null), m.name))); - return; - } else if (m.base_interface_method != null) { - var base_iface = (Interface) m.base_interface_method.parent_symbol; - - set_cvalue (expr, new CCodeIdentifier ("%s_base_%s".printf (get_ccode_lower_case_name (base_iface, null), m.name))); - return; - } - } - - if (m.base_method != null) { - if (!method_has_wrapper (m.base_method)) { - var inst = pub_inst; - if (expr.inner != null && !expr.inner.is_pure ()) { - // instance expression has side-effects - // store in temp. variable - var temp_var = get_temp_variable (expr.inner.value_type); - emit_temp_var (temp_var); - var ctemp = new CCodeIdentifier (temp_var.name); - inst = new CCodeAssignment (ctemp, pub_inst); - set_cvalue (expr.inner, ctemp); - } - var base_class = (Class) m.base_method.parent_symbol; - var vclass = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS".printf (get_ccode_upper_case_name (base_class, null)))); - vclass.add_argument (inst); - set_cvalue (expr, new CCodeMemberAccess.pointer (vclass, m.name)); - } else { - set_cvalue (expr, new CCodeIdentifier (get_ccode_name (m.base_method))); - } - } else if (m.base_interface_method != null) { - set_cvalue (expr, new CCodeIdentifier (get_ccode_name (m.base_interface_method))); - } else if (m is CreationMethod) { - set_cvalue (expr, new CCodeIdentifier (get_ccode_real_name (m))); - } else { - set_cvalue (expr, new CCodeIdentifier (get_ccode_name (m))); - } - } else if (expr.symbol_reference is ArrayLengthField) { - var array_type = (ArrayType) expr.inner.value_type; - if (array_type.fixed_length) { - var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof")); - csizeof.add_argument (pub_inst); - var csizeofelement = new CCodeFunctionCall (new CCodeIdentifier ("sizeof")); - csizeofelement.add_argument (new CCodeElementAccess (pub_inst, new CCodeConstant ("0"))); - set_cvalue (expr, new CCodeBinaryExpression (CCodeBinaryOperator.DIV, csizeof, csizeofelement)); - } else { - set_cvalue (expr, new CCodeMemberAccess (pub_inst, "length")); - } - } else if (expr.symbol_reference is Field) { - var f = (Field) expr.symbol_reference; - expr.target_value = load_field (f, expr.inner != null ? expr.inner.target_value : null); - } else if (expr.symbol_reference is EnumValue) { - var ev = (EnumValue) expr.symbol_reference; - - generate_enum_declaration ((Enum) ev.parent_symbol, cfile); - - set_cvalue (expr, new CCodeConstant (get_ccode_name (ev))); - } else if (expr.symbol_reference is Constant) { - var c = (Constant) expr.symbol_reference; - - generate_constant_declaration (c, cfile); - - set_cvalue (expr, new CCodeIdentifier (get_ccode_name (c))); - } else if (expr.symbol_reference is Property) { - var prop = (Property) expr.symbol_reference; - - if (!(prop is DynamicProperty)) { - generate_property_accessor_declaration (prop.get_accessor, cfile); - - if (!prop.external && prop.external_package) { - // internal VAPI properties - // only add them once per source file - if (add_generated_external_symbol (prop)) { - visit_property (prop); - } - } - } - - if (expr.inner is BaseAccess) { - if (prop.base_property != null) { - var base_class = (Class) prop.base_property.parent_symbol; - var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (get_ccode_upper_case_name (base_class, null)))); - vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (get_ccode_lower_case_name (current_class, null)))); - - var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, "get_%s".printf (prop.name))); - ccall.add_argument (get_cvalue (expr.inner)); - set_cvalue (expr, ccall); - return; - } else if (prop.base_interface_property != null) { - var base_iface = (Interface) prop.base_interface_property.parent_symbol; - string parent_iface_var = "%s_%s_parent_iface".printf (get_ccode_lower_case_name (current_class, null), get_ccode_lower_case_name (base_iface, null)); - - var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (new CCodeIdentifier (parent_iface_var), "get_%s".printf (prop.name))); - ccall.add_argument (get_cvalue (expr.inner)); - set_cvalue (expr, ccall); - return; - } - } - - var base_property = prop; - if (prop.base_property != null) { - base_property = prop.base_property; - } else if (prop.base_interface_property != null) { - base_property = prop.base_interface_property; - } - string getter_cname = get_ccode_name (base_property.get_accessor); - var ccall = new CCodeFunctionCall (new CCodeIdentifier (getter_cname)); - - if (prop.binding == MemberBinding.INSTANCE) { - ccall.add_argument (pub_inst); - } - - set_cvalue (expr, ccall); - } else if (expr.symbol_reference is LocalVariable) { - var local = (LocalVariable) expr.symbol_reference; - expr.target_value = load_local (local); - } else if (expr.symbol_reference is Parameter) { - var p = (Parameter) expr.symbol_reference; - expr.target_value = load_parameter (p); - } - } - - public TargetValue get_local_cvalue (LocalVariable local) { - var result = new DovaValue (local.variable_type); - - if (local.is_result) { - // used in postconditions - result.cvalue = new CCodeIdentifier ("result"); - } else if (local.captured) { - // captured variables are stored on the heap - var block = (Block) local.parent_symbol; - result.cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_variable_cname (local.name)); - } else { - result.cvalue = get_variable_cexpression (local.name); - } - - return result; - } - - public TargetValue get_parameter_cvalue (Parameter p) { - var result = new DovaValue (p.variable_type); - - if (p.name == "this") { - if (current_method != null && current_method.coroutine) { - // use closure - result.cvalue = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "this"); - } else { - var st = current_type_symbol as Struct; - if (st != null && !st.is_boolean_type () && !st.is_integer_type () && !st.is_floating_type () && (!st.is_simple_type () || current_method is CreationMethod)) { - result.cvalue = new CCodeIdentifier ("(*this)"); - } else { - result.cvalue = new CCodeIdentifier ("this"); - } - } - } else { - if (p.captured) { - // captured variables are stored on the heap - var block = p.parent_symbol as Block; - if (block == null) { - block = ((Method) p.parent_symbol).body; - } - result.cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_variable_cname (p.name)); - } else { - if (current_method != null && current_method.coroutine) { - // use closure - result.cvalue = get_variable_cexpression (p.name); - } else { - var type_as_struct = p.variable_type.data_type as Struct; - if (p.direction != ParameterDirection.IN - || (type_as_struct != null && !type_as_struct.is_simple_type () && !p.variable_type.nullable)) { - if (p.variable_type is GenericType) { - result.cvalue = get_variable_cexpression (p.name); - } else { - result.cvalue = new CCodeIdentifier ("(*%s)".printf (get_variable_cname (p.name))); - } - } else { - // Property setters of non simple structs shall replace all occurences - // of the "value" formal parameter with a dereferencing version of that - // parameter. - if (current_property_accessor != null && - current_property_accessor.writable && - current_property_accessor.value_parameter == p && - current_property_accessor.prop.property_type.is_real_struct_type ()) { - result.cvalue = new CCodeIdentifier ("(*value)"); - } else { - result.cvalue = get_variable_cexpression (p.name); - } - } - } - } - } - - return result; - } - - public TargetValue get_field_cvalue (Field f, TargetValue? instance) { - var result = new DovaValue (f.variable_type); - - if (f.binding == MemberBinding.INSTANCE) { - CCodeExpression pub_inst = null; - - if (instance != null) { - pub_inst = get_cvalue_ (instance); - } - - var instance_target_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol); - - var cl = instance_target_type.data_type as Class; - bool dova_priv = false; - if ((f.access == SymbolAccessibility.PRIVATE || f.access == SymbolAccessibility.INTERNAL)) { - dova_priv = true; - } - - CCodeExpression inst; - if (dova_priv) { - var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (get_ccode_upper_case_name (cl, null)))); - priv_call.add_argument (pub_inst); - inst = priv_call; - } else { - inst = pub_inst; - } - if (instance_target_type.data_type.is_reference_type () || (instance != null && instance.value_type is PointerType)) { - result.cvalue = new CCodeMemberAccess.pointer (inst, get_ccode_name (f)); - } else { - result.cvalue = new CCodeMemberAccess (inst, get_ccode_name (f)); - } - } else { - generate_field_declaration (f, cfile); - - result.cvalue = new CCodeIdentifier (get_ccode_name (f)); - } - - return result; - } - - TargetValue load_variable (Variable variable, TargetValue value) { - return value; - } - - public override TargetValue load_local (LocalVariable local) { - return load_variable (local, get_local_cvalue (local)); - } - - public override TargetValue load_parameter (Parameter param) { - return load_variable (param, get_parameter_cvalue (param)); - } - - public override TargetValue load_field (Field field, TargetValue? instance) { - return load_variable (field, get_field_cvalue (field, instance)); - } -} - diff --git a/codegen/valadovamethodcallmodule.vala b/codegen/valadovamethodcallmodule.vala deleted file mode 100644 index a829d6197..000000000 --- a/codegen/valadovamethodcallmodule.vala +++ /dev/null @@ -1,234 +0,0 @@ -/* valadovamethodcallmodule.vala - * - * Copyright (C) 2006-2010 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.1 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 - */ - -public class Vala.DovaMethodCallModule : DovaAssignmentModule { - public override void visit_method_call (MethodCall expr) { - // the bare function call - var ccall = new CCodeFunctionCall (get_cvalue (expr.call)); - - Method m = null; - Delegate deleg = null; - List params; - - var ma = expr.call as MemberAccess; - - var itype = expr.call.value_type; - params = itype.get_parameters (); - - if (itype is MethodType) { - assert (ma != null); - m = ((MethodType) itype).method_symbol; - } else if (itype is ObjectType) { - // constructor - var cl = (Class) ((ObjectType) itype).type_symbol; - m = cl.default_construction_method; - generate_method_declaration (m, cfile); - ccall = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_real_name (m))); - } else if (itype is DelegateType) { - deleg = ((DelegateType) itype).delegate_symbol; - ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_invoke".printf (get_ccode_lower_case_name (deleg)))); - ccall.add_argument (get_cvalue (expr.call)); - } - - if (m is CreationMethod) { - var cl = (Class) m.parent_symbol; - - if (cl == current_class) { - ccall.add_argument (new CCodeIdentifier ("this")); - } else { - ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("this"), get_ccode_name (cl) + "*")); - } - } else if (m != null) { - if (m.binding == MemberBinding.INSTANCE) { - var instance = get_cvalue (ma.inner); - - if (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference) { - var inner_ma = (MemberAccess) ma.inner; - instance = get_cvalue (inner_ma.inner); - } - - var st = m.parent_symbol as Struct; - if (st != null && !st.is_simple_type ()) { - // we need to pass struct instance by reference - var unary = instance as CCodeUnaryExpression; - if (unary != null && unary.operator == CCodeUnaryOperator.POINTER_INDIRECTION) { - // *expr => expr - instance = unary.inner; - } else if (instance is CCodeIdentifier || instance is CCodeMemberAccess) { - instance = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance); - } else { - // if instance is e.g. a function call, we can't take the address of the expression - // (tmp = expr, &tmp) - var ccomma = new CCodeCommaExpression (); - - var temp_var = get_temp_variable (ma.inner.target_type); - emit_temp_var (temp_var); - ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), instance)); - ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name))); - - instance = ccomma; - } - } - - if (ma.inner is BaseAccess) { - ccall.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (current_class.base_class))))); - } - ccall.add_argument (instance); - } - - if (m.binding != MemberBinding.INSTANCE && m.parent_symbol is ObjectTypeSymbol) { - // support static methods in generic types - var type_symbol = (ObjectTypeSymbol) m.parent_symbol; - if (type_symbol.get_type_parameters ().size > 0 && ma.inner is MemberAccess) { - var type_ma = (MemberAccess) ma.inner; - add_generic_type_arguments (ccall, type_ma.get_type_arguments (), expr); - } - } - if (m.get_type_parameters ().size > 0) { - add_generic_type_arguments (ccall, ma.get_type_arguments (), expr); - } - } - - // the complete call expression, might include casts, comma expressions, and/or assignments - CCodeExpression ccall_expr = ccall; - - bool ellipsis = false; - - int i = 1; - Iterator params_it = params.iterator (); - foreach (Expression arg in expr.get_argument_list ()) { - CCodeExpression cexpr = get_cvalue (arg); - - if (params_it.next ()) { - var param = params_it.get (); - ellipsis = param.params_array || param.ellipsis; - if (!ellipsis) { - cexpr = handle_struct_argument (param, arg, cexpr); - - // unref old value for non-null non-weak ref/out arguments - // disabled for arrays for now as that requires special handling - // (ret_tmp = call (&tmp), var1 = (assign_tmp = dup (tmp), free (var1), assign_tmp), ret_tmp) - if (param.direction != ParameterDirection.IN && requires_destroy (arg.value_type) - && (param.direction == ParameterDirection.OUT || !param.variable_type.value_owned) - && !(param.variable_type is ArrayType)) { - var unary = (UnaryExpression) arg; - - var ccomma = new CCodeCommaExpression (); - - var temp_var = get_temp_variable (param.variable_type, param.variable_type.value_owned); - emit_temp_var (temp_var); - cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name)); - - if (param.direction == ParameterDirection.REF) { - var crefcomma = new CCodeCommaExpression (); - crefcomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), get_cvalue (unary.inner))); - crefcomma.append_expression (cexpr); - cexpr = crefcomma; - } - - // call function - LocalVariable ret_temp_var = null; - if (itype.get_return_type () is VoidType) { - ccomma.append_expression (ccall_expr); - } else { - ret_temp_var = get_temp_variable (itype.get_return_type ()); - emit_temp_var (ret_temp_var); - ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (ret_temp_var.name), ccall_expr)); - } - - var cassign_comma = new CCodeCommaExpression (); - - var assign_temp_var = get_temp_variable (unary.inner.value_type, unary.inner.value_type.value_owned); - emit_temp_var (assign_temp_var); - - cassign_comma.append_expression (new CCodeAssignment (get_variable_cexpression (assign_temp_var.name), transform_expression (get_variable_cexpression (temp_var.name), param.variable_type, unary.inner.value_type, arg))); - - // unref old value - cassign_comma.append_expression (get_unref_expression (get_cvalue (unary.inner), arg.value_type, arg)); - - cassign_comma.append_expression (get_variable_cexpression (assign_temp_var.name)); - - // assign new value - ccomma.append_expression (new CCodeAssignment (get_cvalue (unary.inner), cassign_comma)); - - // return value - if (!(itype.get_return_type () is VoidType)) { - ccomma.append_expression (get_variable_cexpression (ret_temp_var.name)); - } - - ccall_expr = ccomma; - } - - if (CCodeBaseModule.get_ccode_type (param) != null) { - cexpr = new CCodeCastExpression (cexpr, CCodeBaseModule.get_ccode_type (param)); - } - } - } - - ccall.add_argument (cexpr); - - i++; - } - if (params_it.next ()) { - var param = params_it.get (); - - /* if there are more parameters than arguments, - * the additional parameter is an ellipsis parameter - * otherwise there is a bug in the semantic analyzer - */ - assert (param.params_array || param.ellipsis); - ellipsis = true; - } - - if (itype.get_return_type () is GenericType) { - var ccomma = new CCodeCommaExpression (); - - var temp_var = get_temp_variable (expr.value_type); - emit_temp_var (temp_var); - if (expr.value_type is GenericType) { - ccall.add_argument (get_variable_cexpression (temp_var.name)); - } else { - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name))); - } - - // call function - ccomma.append_expression (ccall_expr); - - ccomma.append_expression (get_variable_cexpression (temp_var.name)); - - ccall_expr = ccomma; - } - - if (expr.parent_node is ExpressionStatement) { - ccode.add_expression (ccall_expr); - } else { - var temp_var = get_temp_variable (expr.value_type); - var temp_ref = get_variable_cexpression (temp_var.name); - - emit_temp_var (temp_var); - - ccode.add_assignment (temp_ref, ccall_expr); - set_cvalue (expr, temp_ref); - } - } -} - diff --git a/codegen/valadovamethodmodule.vala b/codegen/valadovamethodmodule.vala deleted file mode 100644 index b195fc689..000000000 --- a/codegen/valadovamethodmodule.vala +++ /dev/null @@ -1,42 +0,0 @@ -/* valadovamethodmodule.vala - * - * Copyright (C) 2007-2009 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.1 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 - */ - -/** - * The link between a method and generated code. - */ -public abstract class Vala.DovaMethodModule : DovaStructModule { - public override bool method_has_wrapper (Method method) { - return (method.get_attribute ("NoWrapper") == null); - } - - public override string? get_custom_creturn_type (Method m) { - var attr = m.get_attribute ("CCode"); - if (attr != null) { - string type = attr.get_string ("type"); - if (type != null) { - return type; - } - } - return null; - } -} - diff --git a/codegen/valadovaobjectmodule.vala b/codegen/valadovaobjectmodule.vala deleted file mode 100644 index f8ba003e9..000000000 --- a/codegen/valadovaobjectmodule.vala +++ /dev/null @@ -1,1977 +0,0 @@ -/* valadovaobjectmodule.vala - * - * Copyright (C) 2009-2011 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.1 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 - */ - -public class Vala.DovaObjectModule : DovaArrayModule { - public override void generate_class_declaration (Class cl, CCodeFile decl_space) { - if (add_symbol_declaration (decl_space, cl, get_ccode_name (cl))) { - return; - } - - if (cl.base_class == null) { - decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (get_ccode_name (cl)), new CCodeVariableDeclarator (get_ccode_name (cl)))); - } else if (cl == string_type.data_type) { - generate_class_declaration (cl.base_class, decl_space); - decl_space.add_type_declaration (new CCodeTypeDefinition ("const uint8_t *", new CCodeVariableDeclarator (get_ccode_name (cl)))); - } else { - // typedef to base class instead of dummy struct to avoid warnings/casts - generate_class_declaration (cl.base_class, decl_space); - decl_space.add_type_declaration (new CCodeTypeDefinition (get_ccode_name (cl.base_class), new CCodeVariableDeclarator (get_ccode_name (cl)))); - } - - if (cl.base_class == null) { - var instance_struct = new CCodeStruct ("_%s".printf (get_ccode_name (cl))); - instance_struct.add_field ("DovaType *", "type"); - decl_space.add_type_definition (instance_struct); - } else if (cl == type_class) { - var value_copy_function = new CCodeFunction ("dova_type_value_copy"); - value_copy_function.add_parameter (new CCodeParameter ("type", "DovaType *")); - value_copy_function.add_parameter (new CCodeParameter ("dest", "void *")); - value_copy_function.add_parameter (new CCodeParameter ("dest_index", "intptr_t")); - value_copy_function.add_parameter (new CCodeParameter ("src", "void *")); - value_copy_function.add_parameter (new CCodeParameter ("src_index", "intptr_t")); - - cfile.add_function_declaration (value_copy_function); - - var value_equals_function = new CCodeFunction ("dova_type_value_equals", "bool"); - value_equals_function.add_parameter (new CCodeParameter ("type", "DovaType *")); - value_equals_function.add_parameter (new CCodeParameter ("value", "void *")); - value_equals_function.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - value_equals_function.add_parameter (new CCodeParameter ("other", "void *")); - value_equals_function.add_parameter (new CCodeParameter ("other_index", "intptr_t")); - - cfile.add_function_declaration (value_equals_function); - - var value_hash_function = new CCodeFunction ("dova_type_value_hash", "uintptr_t"); - value_hash_function.add_parameter (new CCodeParameter ("type", "DovaType *")); - value_hash_function.add_parameter (new CCodeParameter ("value", "void *")); - value_hash_function.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - - cfile.add_function_declaration (value_hash_function); - } - - if (cl.base_class != null) { - // cycle Object -> any -> Type -> Object needs to be broken to get correct declaration order - generate_class_declaration (type_class, decl_space); - } - generate_method_declaration ((Method) object_class.scope.lookup ("ref"), decl_space); - generate_method_declaration ((Method) object_class.scope.lookup ("unref"), decl_space); - - var type_fun = new CCodeFunction ("%s_type_get".printf (get_ccode_lower_case_name (cl)), "DovaType *"); - if (cl.is_internal_symbol ()) { - type_fun.modifiers = CCodeModifiers.STATIC; - } - foreach (var type_param in cl.get_type_parameters ()) { - type_fun.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType *")); - } - decl_space.add_function_declaration (type_fun); - - var type_init_fun = new CCodeFunction ("%s_type_init".printf (get_ccode_lower_case_name (cl))); - if (cl.is_internal_symbol ()) { - type_init_fun.modifiers = CCodeModifiers.STATIC; - } - type_init_fun.add_parameter (new CCodeParameter ("type", "DovaType *")); - foreach (var type_param in cl.get_type_parameters ()) { - type_init_fun.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType *")); - } - decl_space.add_function_declaration (type_init_fun); - } - - void generate_virtual_method_declaration (Method m, CCodeFile decl_space, CCodeStruct type_struct) { - if (!m.is_abstract && !m.is_virtual) { - return; - } - - // add vfunc field to the type struct - var vdeclarator = new CCodeFunctionDeclarator (get_ccode_vfunc_name (m)); - - generate_cparameters (m, decl_space, new CCodeFunction ("fake"), vdeclarator); - - var vdecl = new CCodeDeclaration (get_ccode_name (m.return_type)); - vdecl.add_declarator (vdeclarator); - type_struct.add_declaration (vdecl); - } - - bool has_instance_struct (Class cl) { - foreach (Field f in cl.get_fields ()) { - if (f.binding == MemberBinding.INSTANCE) { - return true; - } - } - return false; - } - - bool has_type_struct (Class cl) { - if (cl.get_type_parameters ().size > 0) { - return true; - } - foreach (Method m in cl.get_methods ()) { - if (m.is_abstract || m.is_virtual) { - return true; - } - } - foreach (Property prop in cl.get_properties ()) { - if (prop.is_abstract || prop.is_virtual) { - return true; - } - } - return false; - } - - void generate_class_private_declaration (Class cl, CCodeFile decl_space) { - if (add_symbol_declaration (decl_space, cl, get_ccode_name (cl) + "Private")) { - return; - } - - var instance_priv_struct = new CCodeStruct ("_%sPrivate".printf (get_ccode_name (cl))); - var type_priv_struct = new CCodeStruct ("_%sTypePrivate".printf (get_ccode_name (cl))); - - foreach (Field f in cl.get_fields ()) { - if (f.binding == MemberBinding.INSTANCE) { - generate_type_declaration (f.variable_type, decl_space); - - string field_ctype = get_ccode_name (f.variable_type); - if (f.is_volatile) { - field_ctype = "volatile " + field_ctype; - } - - instance_priv_struct.add_field (field_ctype, get_ccode_name (f) + get_ccode_declarator_suffix (f.variable_type)); - } - } - - if (cl.get_full_name () == "Dova.Type") { - var vdeclarator = new CCodeFunctionDeclarator ("value_copy"); - vdeclarator.add_parameter (new CCodeParameter ("dest", "void *")); - vdeclarator.add_parameter (new CCodeParameter ("dest_index", "intptr_t")); - vdeclarator.add_parameter (new CCodeParameter ("src", "void *")); - vdeclarator.add_parameter (new CCodeParameter ("src_index", "intptr_t")); - - var vdecl = new CCodeDeclaration ("void"); - vdecl.add_declarator (vdeclarator); - instance_priv_struct.add_declaration (vdecl); - - vdeclarator = new CCodeFunctionDeclarator ("value_equals"); - vdeclarator.add_parameter (new CCodeParameter ("value", "void *")); - vdeclarator.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - vdeclarator.add_parameter (new CCodeParameter ("other", "void *")); - vdeclarator.add_parameter (new CCodeParameter ("other_index", "intptr_t")); - - vdecl = new CCodeDeclaration ("bool"); - vdecl.add_declarator (vdeclarator); - instance_priv_struct.add_declaration (vdecl); - - vdeclarator = new CCodeFunctionDeclarator ("value_hash"); - vdeclarator.add_parameter (new CCodeParameter ("value", "void *")); - vdeclarator.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - - vdecl = new CCodeDeclaration ("uintptr_t"); - vdecl.add_declarator (vdeclarator); - instance_priv_struct.add_declaration (vdecl); - - vdeclarator = new CCodeFunctionDeclarator ("value_to_any"); - vdeclarator.add_parameter (new CCodeParameter ("value", "void *")); - vdeclarator.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - - vdecl = new CCodeDeclaration ("DovaObject *"); - vdecl.add_declarator (vdeclarator); - instance_priv_struct.add_declaration (vdecl); - - vdeclarator = new CCodeFunctionDeclarator ("value_from_any"); - vdeclarator.add_parameter (new CCodeParameter ("any_", "any *")); - vdeclarator.add_parameter (new CCodeParameter ("value", "void *")); - vdeclarator.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - - vdecl = new CCodeDeclaration ("void"); - vdecl.add_declarator (vdeclarator); - instance_priv_struct.add_declaration (vdecl); - } - - foreach (var type_param in cl.get_type_parameters ()) { - var type_param_decl = new CCodeDeclaration ("DovaType *"); - type_param_decl.add_declarator (new CCodeVariableDeclarator ("%s_type".printf (type_param.name.down ()))); - type_priv_struct.add_declaration (type_param_decl); - } - - foreach (Method m in cl.get_methods ()) { - generate_virtual_method_declaration (m, decl_space, type_priv_struct); - } - - foreach (Property prop in cl.get_properties ()) { - if (!prop.is_abstract && !prop.is_virtual) { - continue; - } - generate_type_declaration (prop.property_type, decl_space); - - var t = (ObjectTypeSymbol) prop.parent_symbol; - - var this_type = new ObjectType (t); - var cselfparam = new CCodeParameter ("this", get_ccode_name (this_type)); - var cvalueparam = new CCodeParameter ("value", get_ccode_name (prop.property_type)); - - if (prop.get_accessor != null) { - var vdeclarator = new CCodeFunctionDeclarator ("get_%s".printf (prop.name)); - vdeclarator.add_parameter (cselfparam); - string creturn_type = get_ccode_name (prop.property_type); - - var vdecl = new CCodeDeclaration (creturn_type); - vdecl.add_declarator (vdeclarator); - type_priv_struct.add_declaration (vdecl); - } - if (prop.set_accessor != null) { - var vdeclarator = new CCodeFunctionDeclarator ("set_%s".printf (prop.name)); - vdeclarator.add_parameter (cselfparam); - vdeclarator.add_parameter (cvalueparam); - - var vdecl = new CCodeDeclaration ("void"); - vdecl.add_declarator (vdeclarator); - type_priv_struct.add_declaration (vdecl); - } - } - - if (!instance_priv_struct.is_empty) { - decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (instance_priv_struct.name), new CCodeVariableDeclarator ("%sPrivate".printf (get_ccode_name (cl))))); - decl_space.add_type_definition (instance_priv_struct); - } - - if (!type_priv_struct.is_empty) { - decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (type_priv_struct.name), new CCodeVariableDeclarator ("%sTypePrivate".printf (get_ccode_name (cl))))); - decl_space.add_type_definition (type_priv_struct); - } - - var cdecl = new CCodeDeclaration ("intptr_t"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_%s_object_offset".printf (get_ccode_lower_case_name (cl)), new CCodeConstant ("0"))); - cdecl.modifiers = CCodeModifiers.STATIC; - decl_space.add_type_member_declaration (cdecl); - - CCodeExpression type_offset; - - string macro; - if (cl.base_class == null) { - // offset of any class is 0 - macro = "((%sPrivate *) o)".printf (get_ccode_name (cl)); - type_offset = new CCodeConstant ("sizeof (anyPrivate) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate)"); - } else if (cl == object_class) { - macro = "((%sPrivate *) (((char *) o) + sizeof (anyPrivate)))".printf (get_ccode_name (cl)); - type_offset = new CCodeConstant ("sizeof (anyPrivate) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate) + sizeof (anyTypePrivate)"); - } else if (cl == type_class) { - macro = "((%sPrivate *) (((char *) o) + sizeof (anyPrivate) + sizeof (DovaObjectPrivate)))".printf (get_ccode_name (cl)); - type_offset = new CCodeConstant ("sizeof (anyPrivate) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate) + sizeof (anyTypePrivate) + sizeof (DovaObjectTypePrivate)"); - } else { - macro = "((%sPrivate *) (((char *) o) + _%s_object_offset))".printf (get_ccode_name (cl), get_ccode_lower_case_name (cl)); - type_offset = new CCodeConstant ("0"); - } - if (!instance_priv_struct.is_empty) { - decl_space.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (get_ccode_upper_case_name (cl, null)), macro)); - } - - cdecl = new CCodeDeclaration ("intptr_t"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_%s_type_offset".printf (get_ccode_lower_case_name (cl)), type_offset)); - cdecl.modifiers = CCodeModifiers.STATIC; - decl_space.add_type_member_declaration (cdecl); - } - - CCodeFunction create_set_value_copy_function (bool decl_only = false) { - var result = new CCodeFunction ("dova_type_set_value_copy"); - result.add_parameter (new CCodeParameter ("type", "DovaType *")); - result.add_parameter (new CCodeParameter ("(*function) (void *dest, intptr_t dest_index, void *src, intptr_t src_index)", "void")); - if (decl_only) { - return result; - } - - result.block = new CCodeBlock (); - - var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE")); - priv_call.add_argument (new CCodeIdentifier ("type")); - - result.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (priv_call, "value_copy"), new CCodeIdentifier ("function")))); - return result; - } - - public void declare_set_value_copy_function (CCodeFile decl_space) { - if (add_symbol_declaration (decl_space, type_class, "dova_type_set_value_copy")) { - return; - } - decl_space.add_function_declaration (create_set_value_copy_function (true)); - } - - CCodeFunction create_set_value_equals_function (bool decl_only = false) { - var result = new CCodeFunction ("dova_type_set_value_equals"); - result.add_parameter (new CCodeParameter ("type", "DovaType *")); - result.add_parameter (new CCodeParameter ("(*function) (void *value, intptr_t value_index, void *other, intptr_t other_index)", "bool")); - if (decl_only) { - return result; - } - - result.block = new CCodeBlock (); - - var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE")); - priv_call.add_argument (new CCodeIdentifier ("type")); - - result.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (priv_call, "value_equals"), new CCodeIdentifier ("function")))); - return result; - } - - public void declare_set_value_equals_function (CCodeFile decl_space) { - if (add_symbol_declaration (decl_space, type_class, "dova_type_set_value_equals")) { - return; - } - decl_space.add_function_declaration (create_set_value_equals_function (true)); - } - - CCodeFunction create_set_value_hash_function (bool decl_only = false) { - var result = new CCodeFunction ("dova_type_set_value_hash"); - result.add_parameter (new CCodeParameter ("type", "DovaType *")); - result.add_parameter (new CCodeParameter ("(*function) (void *value, intptr_t value_index)", "uintptr_t")); - if (decl_only) { - return result; - } - - result.block = new CCodeBlock (); - - var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE")); - priv_call.add_argument (new CCodeIdentifier ("type")); - - result.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (priv_call, "value_hash"), new CCodeIdentifier ("function")))); - return result; - } - - public void declare_set_value_hash_function (CCodeFile decl_space) { - if (add_symbol_declaration (decl_space, type_class, "dova_type_set_value_hash")) { - return; - } - decl_space.add_function_declaration (create_set_value_hash_function (true)); - } - - CCodeFunction create_set_value_to_any_function (bool decl_only = false) { - var result = new CCodeFunction ("dova_type_set_value_to_any"); - result.add_parameter (new CCodeParameter ("type", "DovaType *")); - result.add_parameter (new CCodeParameter ("(*function) (void *value, intptr_t value_index)", "DovaObject *")); - if (decl_only) { - return result; - } - - result.block = new CCodeBlock (); - - var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE")); - priv_call.add_argument (new CCodeIdentifier ("type")); - - result.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (priv_call, "value_to_any"), new CCodeIdentifier ("function")))); - return result; - } - - public void declare_set_value_to_any_function (CCodeFile decl_space) { - if (add_symbol_declaration (decl_space, type_class, "dova_type_set_value_to_any")) { - return; - } - decl_space.add_function_declaration (create_set_value_to_any_function (true)); - } - - CCodeFunction create_set_value_from_any_function (bool decl_only = false) { - var result = new CCodeFunction ("dova_type_set_value_from_any"); - result.add_parameter (new CCodeParameter ("type", "DovaType *")); - result.add_parameter (new CCodeParameter ("(*function) (DovaObject *any, void *value, intptr_t value_index)", "void")); - if (decl_only) { - return result; - } - - result.block = new CCodeBlock (); - - var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE")); - priv_call.add_argument (new CCodeIdentifier ("type")); - - result.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (priv_call, "value_from_any"), new CCodeIdentifier ("function")))); - return result; - } - - public void declare_set_value_from_any_function (CCodeFile decl_space) { - if (add_symbol_declaration (decl_space, type_class, "dova_type_set_value_from_any")) { - return; - } - decl_space.add_function_declaration (create_set_value_from_any_function (true)); - } - - public CCodeBlock generate_type_get_function (TypeSymbol cl, Class? base_class) { - DataType? base_class_type = null; - if (base_class != null && cl is Class) { - foreach (DataType base_type in ((Class) cl).get_base_types ()) { - if (base_type.data_type == base_class) { - base_class_type = base_type; - break; - } - } - } - - var cdecl = new CCodeDeclaration ("DovaType *"); - cdecl.add_declarator (new CCodeVariableDeclarator ("%s_type".printf (get_ccode_lower_case_name (cl)), new CCodeConstant ("NULL"))); - cdecl.modifiers = CCodeModifiers.STATIC; - cfile.add_type_member_declaration (cdecl); - - var type_fun = new CCodeFunction ("%s_type_get".printf (get_ccode_lower_case_name (cl)), "DovaType *"); - if (cl.is_internal_symbol ()) { - type_fun.modifiers = CCodeModifiers.STATIC; - } - - var object_type_symbol = cl as ObjectTypeSymbol; - if (object_type_symbol != null) { - foreach (var type_param in object_type_symbol.get_type_parameters ()) { - type_fun.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType *")); - } - } - - type_fun.block = new CCodeBlock (); - - var type_init_block = new CCodeBlock (); - - if (base_class == null) { - var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof")); - sizeof_call.add_argument (new CCodeIdentifier ("%sPrivate".printf (get_ccode_name (cl)))); - - var calloc_call = new CCodeFunctionCall (new CCodeIdentifier ("calloc")); - calloc_call.add_argument (new CCodeConstant ("1")); - calloc_call.add_argument (new CCodeConstant ("sizeof (anyPrivate) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate) + sizeof (anyTypePrivate)")); - - type_init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl))), calloc_call))); - - var set_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_object_size")); - set_size.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl)))); - set_size.add_argument (sizeof_call); - type_init_block.add_statement (new CCodeExpressionStatement (set_size)); - - type_init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_any_type_offset"), new CCodeConstant ("sizeof (any) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate)")))); - - set_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_type_size")); - set_size.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl)))); - set_size.add_argument (new CCodeConstant ("sizeof (any) + sizeof (DovaObjectPrivate) + sizeof (DovaTypePrivate) + sizeof (anyTypePrivate)")); - type_init_block.add_statement (new CCodeExpressionStatement (set_size)); - - type_init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl))), "type"), new CCodeFunctionCall (new CCodeIdentifier ("dova_type_type_get"))))); - } else { - generate_method_declaration ((Method) object_class.scope.lookup ("alloc"), cfile); - generate_method_declaration ((Method) type_class.scope.lookup ("alloc"), cfile); - - var base_type = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (base_class)))); - for (int i = 0; i < base_class.get_type_parameters ().size; i++) { - base_type.add_argument (new CCodeConstant ("NULL")); - } - - var alloc_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_alloc")); - alloc_call.add_argument (base_type); - if (!(cl is Class) || has_instance_struct ((Class) cl)) { - alloc_call.add_argument (new CCodeConstant ("sizeof (%sPrivate)".printf (get_ccode_name (cl)))); - } else { - alloc_call.add_argument (new CCodeConstant ("0")); - } - if ((!(cl is Class) || has_type_struct ((Class) cl)) && !(cl is Delegate)) { - alloc_call.add_argument (new CCodeConstant ("sizeof (%sTypePrivate)".printf (get_ccode_name (cl)))); - } else { - alloc_call.add_argument (new CCodeConstant ("0")); - } - alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl))))); - alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_%s_object_offset".printf (get_ccode_lower_case_name (cl))))); - alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_%s_type_offset".printf (get_ccode_lower_case_name (cl))))); - - type_init_block.add_statement (new CCodeExpressionStatement (alloc_call)); - } - - var type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_init".printf (get_ccode_lower_case_name (cl)))); - type_init_call.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl)))); - - if (object_type_symbol != null) { - for (int i = 0; i < object_type_symbol.get_type_parameters ().size; i++) { - type_init_call.add_argument (new CCodeConstant ("NULL")); - } - } - - type_init_block.add_statement (new CCodeExpressionStatement (type_init_call)); - - type_fun.block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl)))), type_init_block)); - - if (object_type_symbol != null && object_type_symbol.get_type_parameters ().size > 0) { - // generics - var specialized_type_get_block = new CCodeBlock (); - - generate_property_accessor_declaration (((Property) type_class.scope.lookup ("next_type")).get_accessor, cfile); - generate_method_declaration ((Method) type_class.scope.lookup ("insert_type"), cfile); - - var first = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_next_type")); - first.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl)))); - - cdecl = new CCodeDeclaration ("DovaType *"); - cdecl.add_declarator (new CCodeVariableDeclarator ("result", first)); - specialized_type_get_block.add_statement (cdecl); - - var next = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_next_type")); - next.add_argument (new CCodeIdentifier ("result")); - - var next_check = new CCodeBlock (); - next_check.add_statement (new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeMemberAccess.pointer (get_type_private_from_type (object_type_symbol, new CCodeIdentifier ("result")), "%s_type".printf (object_type_symbol.get_type_parameters ().get (0).name.down ())), new CCodeIdentifier ("%s_type".printf (object_type_symbol.get_type_parameters ().get (0).name.down ()))), new CCodeBreakStatement ())); - next_check.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), next))); - - specialized_type_get_block.add_statement (new CCodeWhileStatement (new CCodeIdentifier ("result"), next_check)); - - var specialized_type_init_block = new CCodeBlock (); - - generate_method_declaration ((Method) type_class.scope.lookup ("alloc"), cfile); - - var base_type = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (base_class)))); - if (base_class_type != null) { - foreach (var type_arg in base_class_type.get_type_arguments ()) { - base_type.add_argument (get_type_id_expression (type_arg, true)); - } - } - - var alloc_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_alloc")); - alloc_call.add_argument (base_type); - if (!(cl is Class) || has_instance_struct ((Class) cl)) { - alloc_call.add_argument (new CCodeConstant ("sizeof (%sPrivate)".printf (get_ccode_name (cl)))); - } else { - alloc_call.add_argument (new CCodeConstant ("0")); - } - if (!(cl is Class) || has_type_struct ((Class) cl)) { - alloc_call.add_argument (new CCodeConstant ("sizeof (%sTypePrivate)".printf (get_ccode_name (cl)))); - } else { - alloc_call.add_argument (new CCodeConstant ("0")); - } - alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result"))); - alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_%s_object_offset".printf (get_ccode_lower_case_name (cl))))); - alloc_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_%s_type_offset".printf (get_ccode_lower_case_name (cl))))); - - specialized_type_init_block.add_statement (new CCodeExpressionStatement (alloc_call)); - - type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_init".printf (get_ccode_lower_case_name (cl)))); - type_init_call.add_argument (new CCodeIdentifier ("result")); - - foreach (var type_param in object_type_symbol.get_type_parameters ()) { - type_init_call.add_argument (new CCodeIdentifier ("%s_type".printf (type_param.name.down ()))); - } - - specialized_type_init_block.add_statement (new CCodeExpressionStatement (type_init_call)); - - var insert_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_insert_type")); - insert_call.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl)))); - insert_call.add_argument (new CCodeIdentifier ("result")); - specialized_type_init_block.add_statement (new CCodeExpressionStatement (insert_call)); - - specialized_type_get_block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("result")), specialized_type_init_block)); - - specialized_type_get_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result"))); - - type_fun.block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("%s_type".printf (object_type_symbol.get_type_parameters ().get (0).name.down ())), specialized_type_get_block)); - } - - type_fun.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (cl))))); - - cfile.add_function (type_fun); - - var type_init_fun = new CCodeFunction ("%s_type_init".printf (get_ccode_lower_case_name (cl))); - if (cl.is_internal_symbol ()) { - type_init_fun.modifiers = CCodeModifiers.STATIC; - } - type_init_fun.add_parameter (new CCodeParameter ("type", "DovaType *")); - if (object_type_symbol != null) { - foreach (var type_param in object_type_symbol.get_type_parameters ()) { - type_init_fun.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType *")); - } - } - type_init_fun.block = new CCodeBlock (); - - if (base_class == null || cl == object_class || cl == value_class || cl == string_class) { - var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof")); - sizeof_call.add_argument (new CCodeIdentifier ("void *")); - - var set_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_size")); - set_size.add_argument (new CCodeIdentifier ("type")); - set_size.add_argument (sizeof_call); - type_init_fun.block.add_statement (new CCodeExpressionStatement (set_size)); - - declare_set_value_copy_function (cfile); - - var value_copy_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_copy")); - value_copy_call.add_argument (new CCodeIdentifier ("type")); - value_copy_call.add_argument (new CCodeCastExpression (new CCodeIdentifier ("%s_copy".printf (get_ccode_lower_case_name (cl))), "void (*)(void *, intptr_t, void *, intptr_t)")); - type_init_fun.block.add_statement (new CCodeExpressionStatement (value_copy_call)); - - var function = new CCodeFunction ("%s_copy".printf (get_ccode_lower_case_name (cl)), "void"); - function.modifiers = CCodeModifiers.STATIC; - function.add_parameter (new CCodeParameter ("dest", "any **")); - function.add_parameter (new CCodeParameter ("dest_index", "intptr_t")); - function.add_parameter (new CCodeParameter ("src", "any **")); - function.add_parameter (new CCodeParameter ("src_index", "intptr_t")); - - function.block = new CCodeBlock (); - var cfrag = new CCodeFragment (); - function.block.add_statement (cfrag); - - var dest = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("dest"), new CCodeIdentifier ("dest_index")); - var src = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("src"), new CCodeIdentifier ("src_index")); - - var unref_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_unref".printf (get_ccode_lower_case_name (cl)))); - unref_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, dest)); - var unref_block = new CCodeBlock (); - unref_block.add_statement (new CCodeExpressionStatement (unref_call)); - unref_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, dest), new CCodeConstant ("NULL")))); - function.block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, dest), unref_block)); - - var ref_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_ref".printf (get_ccode_lower_case_name (cl)))); - ref_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, src)); - var ref_block = new CCodeBlock (); - ref_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, dest), ref_call))); - function.block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("src"), ref_block)); - - cfile.add_function (function); - - { - var value_equals_fun = new CCodeFunction ("%s_value_equals".printf (get_ccode_lower_case_name (cl)), "bool"); - value_equals_fun.modifiers = CCodeModifiers.STATIC; - value_equals_fun.add_parameter (new CCodeParameter ("value", get_ccode_name (cl) + "**")); - value_equals_fun.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - value_equals_fun.add_parameter (new CCodeParameter ("other", get_ccode_name (cl) + "**")); - value_equals_fun.add_parameter (new CCodeParameter ("other_index", "intptr_t")); - value_equals_fun.block = new CCodeBlock (); - var val = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("value"), new CCodeIdentifier ("value_index")); - var other = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("other"), new CCodeIdentifier ("other_index")); - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("any_equals")); - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, val)); - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, other)); - value_equals_fun.block.add_statement (new CCodeReturnStatement (ccall)); - cfile.add_function (value_equals_fun); - - declare_set_value_equals_function (cfile); - - var value_equals_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_equals")); - value_equals_call.add_argument (new CCodeIdentifier ("type")); - value_equals_call.add_argument (new CCodeCastExpression (new CCodeIdentifier ("%s_value_equals".printf (get_ccode_lower_case_name (cl))), "bool (*)(void *, intptr_t, void *, intptr_t)")); - type_init_fun.block.add_statement (new CCodeExpressionStatement (value_equals_call)); - } - - { - var value_hash_fun = new CCodeFunction ("%s_value_hash".printf (get_ccode_lower_case_name (cl)), "uintptr_t"); - value_hash_fun.modifiers = CCodeModifiers.STATIC; - value_hash_fun.add_parameter (new CCodeParameter ("value", get_ccode_name (cl) + "**")); - value_hash_fun.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - value_hash_fun.block = new CCodeBlock (); - var val = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("value"), new CCodeIdentifier ("value_index")); - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("any_hash")); - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, val)); - value_hash_fun.block.add_statement (new CCodeReturnStatement (ccall)); - cfile.add_function (value_hash_fun); - - declare_set_value_hash_function (cfile); - - var value_hash_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_hash")); - value_hash_call.add_argument (new CCodeIdentifier ("type")); - value_hash_call.add_argument (new CCodeCastExpression (new CCodeIdentifier ("%s_value_hash".printf (get_ccode_lower_case_name (cl))), "uintptr_t (*)(void *, intptr_t)")); - type_init_fun.block.add_statement (new CCodeExpressionStatement (value_hash_call)); - } - - // generate method to box value - var value_to_any_fun = new CCodeFunction ("%s_value_to_any".printf (get_ccode_lower_case_name (cl)), "any*"); - value_to_any_fun.modifiers = CCodeModifiers.STATIC; - value_to_any_fun.add_parameter (new CCodeParameter ("value", get_ccode_name (cl) + "**")); - value_to_any_fun.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - value_to_any_fun.block = new CCodeBlock (); - var val = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("value"), new CCodeIdentifier ("value_index")); - string to_any_fun = "%s_ref".printf (get_ccode_lower_case_name (cl)); - if (cl == string_class) { - to_any_fun = "string_to_any"; - } - var ccall = new CCodeFunctionCall (new CCodeIdentifier (to_any_fun)); - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, val)); - value_to_any_fun.block.add_statement (new CCodeReturnStatement (ccall)); - cfile.add_function (value_to_any_fun); - - declare_set_value_to_any_function (cfile); - - var value_to_any_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_to_any")); - value_to_any_call.add_argument (new CCodeIdentifier ("type")); - value_to_any_call.add_argument (new CCodeIdentifier ("%s_value_to_any".printf (get_ccode_lower_case_name (cl)))); - type_init_fun.block.add_statement (new CCodeExpressionStatement (value_to_any_call)); - - // generate method to unbox value - var value_from_any_fun = new CCodeFunction ("%s_value_from_any".printf (get_ccode_lower_case_name (cl))); - value_from_any_fun.modifiers = CCodeModifiers.STATIC; - value_from_any_fun.add_parameter (new CCodeParameter ("any_", "any *")); - value_from_any_fun.add_parameter (new CCodeParameter ("value", get_ccode_name (cl) + "**")); - value_from_any_fun.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - value_from_any_fun.block = new CCodeBlock (); - string from_any_fun = "%s_ref".printf (get_ccode_lower_case_name (cl)); - if (cl == string_class) { - from_any_fun = "string_from_any"; - } - ccall = new CCodeFunctionCall (new CCodeIdentifier (from_any_fun)); - ccall.add_argument (new CCodeIdentifier ("any_")); - value_from_any_fun.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, val), ccall))); - value_from_any_fun.block.add_statement (new CCodeReturnStatement (ccall)); - cfile.add_function (value_from_any_fun); - - declare_set_value_from_any_function (cfile); - - var value_from_any_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_from_any")); - value_from_any_call.add_argument (new CCodeIdentifier ("type")); - value_from_any_call.add_argument (new CCodeIdentifier ("%s_value_from_any".printf (get_ccode_lower_case_name (cl)))); - type_init_fun.block.add_statement (new CCodeExpressionStatement (value_from_any_call)); - } else { - type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_init".printf (get_ccode_lower_case_name (base_class)))); - type_init_call.add_argument (new CCodeIdentifier ("type")); - - if (base_class_type != null) { - foreach (var type_arg in base_class_type.get_type_arguments ()) { - type_init_call.add_argument (get_type_id_expression (type_arg, true)); - } - } - - type_init_fun.block.add_statement (new CCodeExpressionStatement (type_init_call)); - - if (object_type_symbol != null) { - foreach (var type_param in object_type_symbol.get_type_parameters ()) { - type_init_fun.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_type_private_from_type (object_type_symbol, new CCodeIdentifier ("type")), "%s_type".printf (type_param.name.down ())), new CCodeIdentifier ("%s_type".printf (type_param.name.down ()))))); - } - } - } - - cfile.add_function (type_init_fun); - - return type_init_fun.block; - } - - void add_finalize_function (Class cl) { - var function = new CCodeFunction ("%sfinalize".printf (get_ccode_lower_case_prefix (cl)), "void"); - function.modifiers = CCodeModifiers.STATIC; - - function.add_parameter (new CCodeParameter ("this", get_ccode_name (cl) + "*")); - - push_function (function); - - cfile.add_function_declaration (function); - - if (cl.destructor != null) { - cl.destructor.body.emit (this); - } - - foreach (var f in cl.get_fields ()) { - if (f.binding == MemberBinding.INSTANCE) { - CCodeExpression lhs = null; - if (f.is_internal_symbol ()) { - var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (get_ccode_upper_case_name (cl, null)))); - priv_call.add_argument (new CCodeIdentifier ("this")); - lhs = new CCodeMemberAccess.pointer (priv_call, get_ccode_name (f)); - } else { - lhs = new CCodeMemberAccess.pointer (new CCodeIdentifier ("this"), get_ccode_name (f)); - } - - if (requires_destroy (f.variable_type)) { - var this_access = new MemberAccess.simple ("this"); - this_access.value_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol); - - var field_st = f.parent_symbol as Struct; - if (field_st != null && !field_st.is_simple_type ()) { - set_cvalue (this_access, new CCodeIdentifier ("(*this)")); - } else { - set_cvalue (this_access, new CCodeIdentifier ("this")); - } - - var ma = new MemberAccess (this_access, f.name); - ma.symbol_reference = f; - ccode.add_expression (get_unref_expression (lhs, f.variable_type, ma)); - } - } - } - - // chain up to finalize function of the base class - foreach (DataType base_type in cl.get_base_types ()) { - var object_type = (ObjectType) base_type; - if (object_type.type_symbol is Class) { - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_base_finalize")); - var type_get_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (object_type.type_symbol)))); - foreach (var type_arg in base_type.get_type_arguments ()) { - type_get_call.add_argument (get_type_id_expression (type_arg, false)); - } - ccall.add_argument (type_get_call); - ccall.add_argument (new CCodeIdentifier ("this")); - ccode.add_statement (new CCodeExpressionStatement (ccall)); - } - } - - pop_function (); - - cfile.add_function (function); - } - - public override void visit_class (Class cl) { - push_context (new EmitContext (cl)); - - generate_class_declaration (cl, cfile); - generate_class_private_declaration (cl, cfile); - - if (!cl.is_internal_symbol ()) { - generate_class_declaration (cl, header_file); - } - - cl.accept_children (this); - - var type_init_block = generate_type_get_function (cl, cl.base_class); - - foreach (DataType base_type in cl.get_base_types ()) { - var object_type = (ObjectType) base_type; - if (object_type.type_symbol is Interface) { - generate_interface_declaration ((Interface) object_type.type_symbol, cfile); - - var type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_init".printf (get_ccode_lower_case_name (object_type.type_symbol)))); - type_init_call.add_argument (new CCodeIdentifier ("type")); - foreach (var type_arg in base_type.get_type_arguments ()) { - type_init_call.add_argument (get_type_id_expression (type_arg, true)); - } - type_init_block.add_statement (new CCodeExpressionStatement (type_init_call)); - } - } - - // finalizer - if (cl.base_class != null && !cl.is_fundamental () && (cl.get_fields ().size > 0 || cl.destructor != null)) { - add_finalize_function (cl); - - generate_method_declaration ((Method) object_class.scope.lookup ("finalize"), cfile); - - var override_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_override_finalize")); - override_call.add_argument (new CCodeIdentifier ("type")); - override_call.add_argument (new CCodeIdentifier ("%sfinalize".printf (get_ccode_lower_case_prefix (cl)))); - type_init_block.add_statement (new CCodeExpressionStatement (override_call)); - } - - foreach (Method m in cl.get_methods ()) { - if (m.is_virtual || m.overrides) { - var override_call = new CCodeFunctionCall (new CCodeIdentifier ("%soverride_%s".printf (get_ccode_lower_case_prefix (m.base_method.parent_symbol), m.name))); - override_call.add_argument (new CCodeIdentifier ("type")); - override_call.add_argument (new CCodeIdentifier (get_ccode_real_name (m))); - type_init_block.add_statement (new CCodeExpressionStatement (override_call)); - } else if (m.base_interface_method != null) { - var override_call = new CCodeFunctionCall (new CCodeIdentifier ("%soverride_%s".printf (get_ccode_lower_case_prefix (m.base_interface_method.parent_symbol), m.name))); - override_call.add_argument (new CCodeIdentifier ("type")); - override_call.add_argument (new CCodeIdentifier (get_ccode_real_name (m))); - type_init_block.add_statement (new CCodeExpressionStatement (override_call)); - } - } - - foreach (Property prop in cl.get_properties ()) { - if (prop.is_virtual || prop.overrides) { - if (prop.get_accessor != null) { - var override_call = new CCodeFunctionCall (new CCodeIdentifier ("%soverride_get_%s".printf (get_ccode_lower_case_prefix (prop.base_property.parent_symbol), prop.name))); - override_call.add_argument (new CCodeIdentifier ("type")); - override_call.add_argument (new CCodeIdentifier (get_ccode_name (prop.get_accessor))); - type_init_block.add_statement (new CCodeExpressionStatement (override_call)); - } - if (prop.set_accessor != null) { - var override_call = new CCodeFunctionCall (new CCodeIdentifier ("%soverride_set_%s".printf (get_ccode_lower_case_prefix (prop.base_property.parent_symbol), prop.name))); - override_call.add_argument (new CCodeIdentifier ("type")); - override_call.add_argument (new CCodeIdentifier (get_ccode_name (prop.set_accessor))); - type_init_block.add_statement (new CCodeExpressionStatement (override_call)); - } - } - } - - if (cl == type_class) { - var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("DOVA_TYPE_GET_PRIVATE")); - priv_call.add_argument (new CCodeIdentifier ("type")); - - var value_copy_function = new CCodeFunction ("dova_type_value_copy"); - value_copy_function.add_parameter (new CCodeParameter ("type", "DovaType *")); - value_copy_function.add_parameter (new CCodeParameter ("dest", "void *")); - value_copy_function.add_parameter (new CCodeParameter ("dest_index", "intptr_t")); - value_copy_function.add_parameter (new CCodeParameter ("src", "void *")); - value_copy_function.add_parameter (new CCodeParameter ("src_index", "intptr_t")); - - value_copy_function.block = new CCodeBlock (); - - var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (priv_call, "value_copy")); - ccall.add_argument (new CCodeIdentifier ("dest")); - ccall.add_argument (new CCodeIdentifier ("dest_index")); - ccall.add_argument (new CCodeIdentifier ("src")); - ccall.add_argument (new CCodeIdentifier ("src_index")); - value_copy_function.block.add_statement (new CCodeExpressionStatement (ccall)); - - cfile.add_function (value_copy_function); - - declare_set_value_copy_function (cfile); - declare_set_value_copy_function (header_file); - cfile.add_function (create_set_value_copy_function ()); - - var value_equals_function = new CCodeFunction ("dova_type_value_equals", "bool"); - value_equals_function.add_parameter (new CCodeParameter ("type", "DovaType *")); - value_equals_function.add_parameter (new CCodeParameter ("value", "void *")); - value_equals_function.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - value_equals_function.add_parameter (new CCodeParameter ("other", "void *")); - value_equals_function.add_parameter (new CCodeParameter ("other_index", "intptr_t")); - - value_equals_function.block = new CCodeBlock (); - - ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (priv_call, "value_equals")); - ccall.add_argument (new CCodeIdentifier ("value")); - ccall.add_argument (new CCodeIdentifier ("value_index")); - ccall.add_argument (new CCodeIdentifier ("other")); - ccall.add_argument (new CCodeIdentifier ("other_index")); - value_equals_function.block.add_statement (new CCodeReturnStatement (ccall)); - - cfile.add_function (value_equals_function); - - declare_set_value_equals_function (cfile); - declare_set_value_equals_function (header_file); - cfile.add_function (create_set_value_equals_function ()); - - var value_hash_function = new CCodeFunction ("dova_type_value_hash", "uintptr_t"); - value_hash_function.add_parameter (new CCodeParameter ("type", "DovaType *")); - value_hash_function.add_parameter (new CCodeParameter ("value", "void *")); - value_hash_function.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - - value_hash_function.block = new CCodeBlock (); - - ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (priv_call, "value_hash")); - ccall.add_argument (new CCodeIdentifier ("value")); - ccall.add_argument (new CCodeIdentifier ("value_index")); - value_hash_function.block.add_statement (new CCodeReturnStatement (ccall)); - - cfile.add_function (value_hash_function); - - declare_set_value_hash_function (cfile); - declare_set_value_hash_function (header_file); - cfile.add_function (create_set_value_hash_function ()); - - var value_to_any_function = new CCodeFunction ("dova_type_value_to_any", "DovaObject *"); - value_to_any_function.add_parameter (new CCodeParameter ("type", "DovaType *")); - value_to_any_function.add_parameter (new CCodeParameter ("value", "void *")); - value_to_any_function.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - - value_to_any_function.block = new CCodeBlock (); - - ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (priv_call, "value_to_any")); - ccall.add_argument (new CCodeIdentifier ("value")); - ccall.add_argument (new CCodeIdentifier ("value_index")); - value_to_any_function.block.add_statement (new CCodeReturnStatement (ccall)); - - cfile.add_function (value_to_any_function); - - declare_set_value_to_any_function (cfile); - declare_set_value_to_any_function (header_file); - cfile.add_function (create_set_value_to_any_function ()); - - var value_from_any_function = new CCodeFunction ("dova_type_value_from_any", "void"); - value_from_any_function.add_parameter (new CCodeParameter ("type", "DovaType *")); - value_from_any_function.add_parameter (new CCodeParameter ("any_", "any *")); - value_from_any_function.add_parameter (new CCodeParameter ("value", "void *")); - value_from_any_function.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - - value_from_any_function.block = new CCodeBlock (); - - ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (priv_call, "value_from_any")); - ccall.add_argument (new CCodeIdentifier ("any_")); - ccall.add_argument (new CCodeIdentifier ("value")); - ccall.add_argument (new CCodeIdentifier ("value_index")); - value_from_any_function.block.add_statement (new CCodeReturnStatement (ccall)); - - cfile.add_function (value_from_any_function); - - declare_set_value_from_any_function (cfile); - declare_set_value_from_any_function (header_file); - cfile.add_function (create_set_value_from_any_function ()); - } - - pop_context (); - } - - public override void visit_interface (Interface iface) { - push_context (new EmitContext (iface)); - - generate_interface_declaration (iface, cfile); - - var type_priv_struct = new CCodeStruct ("_%sTypePrivate".printf (get_ccode_name (iface))); - - foreach (var type_param in iface.get_type_parameters ()) { - var type_param_decl = new CCodeDeclaration ("DovaType *"); - type_param_decl.add_declarator (new CCodeVariableDeclarator ("%s_type".printf (type_param.name.down ()))); - type_priv_struct.add_declaration (type_param_decl); - } - - foreach (Method m in iface.get_methods ()) { - generate_virtual_method_declaration (m, cfile, type_priv_struct); - } - - if (!type_priv_struct.is_empty) { - cfile.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (type_priv_struct.name), new CCodeVariableDeclarator ("%sTypePrivate".printf (get_ccode_name (iface))))); - cfile.add_type_definition (type_priv_struct); - } - - var cdecl = new CCodeDeclaration ("DovaType *"); - cdecl.add_declarator (new CCodeVariableDeclarator ("%s_type".printf (get_ccode_lower_case_name (iface)), new CCodeConstant ("NULL"))); - cdecl.modifiers = CCodeModifiers.STATIC; - cfile.add_type_member_declaration (cdecl); - - var type_fun = new CCodeFunction ("%s_type_get".printf (get_ccode_lower_case_name (iface)), "DovaType *"); - if (iface.is_internal_symbol ()) { - type_fun.modifiers = CCodeModifiers.STATIC; - } - foreach (var type_param in iface.get_type_parameters ()) { - type_fun.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType *")); - } - type_fun.block = new CCodeBlock (); - - var type_init_block = new CCodeBlock (); - - var calloc_call = new CCodeFunctionCall (new CCodeIdentifier ("calloc")); - calloc_call.add_argument (new CCodeConstant ("1")); - - if (!type_priv_struct.is_empty) { - calloc_call.add_argument (new CCodeConstant ("dova_type_get_type_size (dova_type_type_get ()) + sizeof (%sTypePrivate)".printf (get_ccode_name (iface)))); - } else { - calloc_call.add_argument (new CCodeConstant ("dova_type_get_type_size (dova_type_type_get ())")); - } - - type_init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (iface))), calloc_call))); - - // call any_type_init to set value_copy and similar functions - var any_type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("any_type_init")); - any_type_init_call.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (iface)))); - type_init_block.add_statement (new CCodeExpressionStatement (any_type_init_call)); - - var type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_init".printf (get_ccode_lower_case_name (iface)))); - type_init_call.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (iface)))); - foreach (var type_param in iface.get_type_parameters ()) { - type_init_call.add_argument (new CCodeIdentifier ("%s_type".printf (type_param.name.down ()))); - } - type_init_block.add_statement (new CCodeExpressionStatement (type_init_call)); - - type_fun.block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (iface)))), type_init_block)); - - type_fun.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (iface))))); - - cfile.add_function (type_fun); - - var type_init_fun = new CCodeFunction ("%s_type_init".printf (get_ccode_lower_case_name (iface))); - if (iface.is_internal_symbol ()) { - type_init_fun.modifiers = CCodeModifiers.STATIC; - } - type_init_fun.add_parameter (new CCodeParameter ("type", "DovaType *")); - foreach (var type_param in iface.get_type_parameters ()) { - type_init_fun.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType *")); - } - type_init_fun.block = new CCodeBlock (); - - foreach (DataType base_type in iface.get_prerequisites ()) { - var object_type = (ObjectType) base_type; - if (object_type.type_symbol is Interface) { - type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_init".printf (get_ccode_lower_case_name (object_type.type_symbol)))); - type_init_call.add_argument (new CCodeIdentifier ("type")); - type_init_fun.block.add_statement (new CCodeExpressionStatement (type_init_call)); - } - } - - var vtable_alloc = new CCodeFunctionCall (new CCodeIdentifier ("calloc")); - vtable_alloc.add_argument (new CCodeConstant ("1")); - vtable_alloc.add_argument (new CCodeConstant ("sizeof (%sTypePrivate)".printf (get_ccode_name (iface)))); - - var type_get_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (iface)))); - foreach (var type_param in iface.get_type_parameters ()) { - type_get_call.add_argument (new CCodeIdentifier ("%s_type".printf (type_param.name.down ()))); - } - - if (!type_priv_struct.is_empty) { - var add_interface_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_add_interface")); - add_interface_call.add_argument (new CCodeIdentifier ("type")); - add_interface_call.add_argument (type_get_call); - add_interface_call.add_argument (vtable_alloc); - type_init_fun.block.add_statement (new CCodeExpressionStatement (add_interface_call)); - } - - cfile.add_function (type_init_fun); - - iface.accept_children (this); - - pop_context (); - } - - public override void generate_property_accessor_declaration (PropertyAccessor acc, CCodeFile decl_space) { - if (add_symbol_declaration (decl_space, acc.prop, get_ccode_name (acc))) { - return; - } - - var prop = (Property) acc.prop; - - generate_type_declaration (acc.value_type, decl_space); - - CCodeFunction function; - - if (acc.readable) { - function = new CCodeFunction (get_ccode_name (acc), get_ccode_name (acc.value_type)); - } else { - function = new CCodeFunction (get_ccode_name (acc), "void"); - } - - if (prop.binding == MemberBinding.INSTANCE) { - DataType this_type; - if (prop.parent_symbol is Struct) { - var st = (Struct) prop.parent_symbol; - this_type = SemanticAnalyzer.get_data_type_for_symbol (st); - } else { - var t = (ObjectTypeSymbol) prop.parent_symbol; - this_type = new ObjectType (t); - } - - generate_type_declaration (this_type, decl_space); - var cselfparam = new CCodeParameter ("this", get_ccode_name (this_type)); - - function.add_parameter (cselfparam); - } - - if (acc.writable) { - var cvalueparam = new CCodeParameter ("value", get_ccode_name (acc.value_type)); - function.add_parameter (cvalueparam); - } - - if (prop.is_internal_symbol () || acc.is_internal_symbol ()) { - function.modifiers |= CCodeModifiers.STATIC; - } - decl_space.add_function_declaration (function); - - if (prop.is_abstract || prop.is_virtual) { - string param_list = "(%s *this".printf (get_ccode_name (prop.parent_symbol)); - if (!acc.readable) { - param_list += ", "; - param_list += get_ccode_name (acc.value_type); - } - param_list += ")"; - - var override_func = new CCodeFunction ("%soverride_%s_%s".printf (get_ccode_lower_case_prefix (prop.parent_symbol), acc.readable ? "get" : "set", prop.name)); - override_func.add_parameter (new CCodeParameter ("type", "DovaType *")); - override_func.add_parameter (new CCodeParameter ("(*function) %s".printf (param_list), acc.readable ? get_ccode_name (acc.value_type) : "void")); - - decl_space.add_function_declaration (override_func); - } - } - - public override void visit_property_accessor (PropertyAccessor acc) { - push_context (new EmitContext (acc)); - - var prop = (Property) acc.prop; - - // do not declare overriding properties and interface implementations - if (prop.is_abstract || prop.is_virtual - || (prop.base_property == null && prop.base_interface_property == null)) { - generate_property_accessor_declaration (acc, cfile); - - if (!prop.is_internal_symbol () - && (acc.access == SymbolAccessibility.PUBLIC - || acc.access == SymbolAccessibility.PROTECTED)) { - generate_property_accessor_declaration (acc, header_file); - } - } - - DataType this_type; - if (prop.parent_symbol is Struct) { - var st = (Struct) prop.parent_symbol; - this_type = SemanticAnalyzer.get_data_type_for_symbol (st); - } else { - var t = (ObjectTypeSymbol) prop.parent_symbol; - this_type = new ObjectType (t); - } - var cselfparam = new CCodeParameter ("this", get_ccode_name (this_type)); - var cvalueparam = new CCodeParameter ("value", get_ccode_name (acc.value_type)); - - string cname = get_ccode_name (acc); - - if (prop.is_abstract || prop.is_virtual) { - CCodeFunction function; - if (acc.readable) { - function = new CCodeFunction (get_ccode_name (acc), get_ccode_name (current_return_type)); - } else { - function = new CCodeFunction (get_ccode_name (acc), "void"); - } - function.add_parameter (cselfparam); - if (acc.writable) { - function.add_parameter (cvalueparam); - } - - if (prop.is_internal_symbol () || !(acc.readable || acc.writable) || acc.is_internal_symbol ()) { - // accessor function should be private if the property is an internal symbol - function.modifiers |= CCodeModifiers.STATIC; - } - - push_function (function); - - var vcast = get_type_private_from_type ((ObjectTypeSymbol) prop.parent_symbol, get_type_from_instance (new CCodeIdentifier ("this"))); - - if (acc.readable) { - var vcall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, "get_%s".printf (prop.name))); - vcall.add_argument (new CCodeIdentifier ("this")); - ccode.add_return (vcall); - } else { - var vcall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, "set_%s".printf (prop.name))); - vcall.add_argument (new CCodeIdentifier ("this")); - vcall.add_argument (new CCodeIdentifier ("value")); - ccode.add_expression (vcall); - } - - pop_function (); - - cfile.add_function (function); - - - string param_list = "(%s *this".printf (get_ccode_name (prop.parent_symbol)); - if (!acc.readable) { - param_list += ", "; - param_list += get_ccode_name (acc.value_type); - } - param_list += ")"; - - var override_func = new CCodeFunction ("%soverride_%s_%s".printf (get_ccode_lower_case_prefix (prop.parent_symbol), acc.readable ? "get" : "set", prop.name)); - override_func.add_parameter (new CCodeParameter ("type", "DovaType *")); - override_func.add_parameter (new CCodeParameter ("(*function) %s".printf (param_list), acc.readable ? get_ccode_name (acc.value_type) : "void")); - - push_function (override_func); - - vcast = get_type_private_from_type ((ObjectTypeSymbol) prop.parent_symbol, new CCodeIdentifier ("type")); - - ccode.add_assignment (new CCodeMemberAccess.pointer (vcast, "%s_%s".printf (acc.readable ? "get" : "set", prop.name)), new CCodeIdentifier ("function")); - - pop_function (); - - cfile.add_function (override_func); - } - - if (!prop.is_abstract) { - CCodeFunction function; - if (acc.writable) { - function = new CCodeFunction (cname, "void"); - } else { - function = new CCodeFunction (cname, get_ccode_name (acc.value_type)); - } - - if (prop.binding == MemberBinding.INSTANCE) { - function.add_parameter (cselfparam); - } - if (acc.writable) { - function.add_parameter (cvalueparam); - } - - if (prop.is_internal_symbol () || !(acc.readable || acc.writable) || acc.is_internal_symbol ()) { - // accessor function should be private if the property is an internal symbol - function.modifiers |= CCodeModifiers.STATIC; - } - - push_function (function); - - acc.body.emit (this); - - if (acc.readable) { - var cdecl = new CCodeDeclaration (get_ccode_name (acc.value_type)); - cdecl.add_declarator (new CCodeVariableDeclarator.zero ("result", default_value_for_type (acc.value_type, true))); - function.block.prepend_statement (cdecl); - - function.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result"))); - } - - cfile.add_function (function); - } - - pop_context (); - } - - public override void generate_interface_declaration (Interface iface, CCodeFile decl_space) { - if (add_symbol_declaration (decl_space, iface, get_ccode_name (iface))) { - return; - } - - // typedef to DovaObject instead of dummy struct to avoid warnings/casts - generate_class_declaration (object_class, decl_space); - decl_space.add_type_declaration (new CCodeTypeDefinition ("DovaObject", new CCodeVariableDeclarator (get_ccode_name (iface)))); - - generate_class_declaration (type_class, decl_space); - - var type_fun = new CCodeFunction ("%s_type_get".printf (get_ccode_lower_case_name (iface)), "DovaType *"); - if (iface.is_internal_symbol ()) { - type_fun.modifiers = CCodeModifiers.STATIC; - } - foreach (var type_param in iface.get_type_parameters ()) { - type_fun.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType *")); - } - decl_space.add_function_declaration (type_fun); - - var type_init_fun = new CCodeFunction ("%s_type_init".printf (get_ccode_lower_case_name (iface))); - if (iface.is_internal_symbol ()) { - type_init_fun.modifiers = CCodeModifiers.STATIC; - } - type_init_fun.add_parameter (new CCodeParameter ("type", "DovaType *")); - foreach (var type_param in iface.get_type_parameters ()) { - type_init_fun.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType *")); - } - decl_space.add_function_declaration (type_init_fun); - } - - - public override bool method_has_wrapper (Method method) { - return (method.get_attribute ("NoWrapper") == null); - } - - public override string? get_custom_creturn_type (Method m) { - var attr = m.get_attribute ("CCode"); - if (attr != null) { - string type = attr.get_string ("type"); - if (type != null) { - return type; - } - } - return null; - } - - public override void generate_method_declaration (Method m, CCodeFile decl_space) { - if (add_symbol_declaration (decl_space, m, get_ccode_name (m))) { - return; - } - - var function = new CCodeFunction (get_ccode_name (m)); - - if (m.is_internal_symbol ()) { - function.modifiers |= CCodeModifiers.STATIC; - if (m.is_inline) { - function.modifiers |= CCodeModifiers.INLINE; - } - } - - generate_cparameters (m, decl_space, function, null, new CCodeFunctionCall (new CCodeIdentifier ("fake"))); - - decl_space.add_function_declaration (function); - - if (m.is_abstract || m.is_virtual) { - var base_func = function.copy (); - base_func.name = "%sbase_%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), m.name); - base_func.insert_parameter (0, new CCodeParameter ("base_type", "DovaType *")); - decl_space.add_function_declaration (base_func); - - string param_list = "(%s *this".printf (get_ccode_name (m.parent_symbol)); - foreach (var param in m.get_parameters ()) { - param_list += ", "; - param_list += get_ccode_name (param.variable_type); - } - if (m.return_type is GenericType) { - param_list += ", void *"; - } - param_list += ")"; - - var override_func = new CCodeFunction ("%soverride_%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), m.name)); - override_func.add_parameter (new CCodeParameter ("type", "DovaType *")); - override_func.add_parameter (new CCodeParameter ("(*function) %s".printf (param_list), (m.return_type is GenericType) ? "void" : get_ccode_name (m.return_type))); - decl_space.add_function_declaration (override_func); - } - - if (m is CreationMethod && m.parent_symbol is Class) { - generate_class_declaration ((Class) m.parent_symbol, decl_space); - - // _init function - function = new CCodeFunction (get_ccode_real_name (m)); - - if (m.is_internal_symbol ()) { - function.modifiers |= CCodeModifiers.STATIC; - } - - generate_cparameters (m, decl_space, function); - - decl_space.add_function_declaration (function); - } - } - - CCodeExpression get_type_from_instance (CCodeExpression instance_expression) { - return new CCodeMemberAccess.pointer (new CCodeCastExpression (instance_expression, "DovaObject *"), "type"); - } - - public override void visit_method (Method m) { - push_context (new EmitContext (m)); - - foreach (Parameter param in m.get_parameters ()) { - param.accept (this); - } - - foreach (Expression precondition in m.get_preconditions ()) { - precondition.emit (this); - } - - foreach (Expression postcondition in m.get_postconditions ()) { - postcondition.emit (this); - } - - - generate_method_declaration (m, cfile); - - if (!m.is_internal_symbol ()) { - generate_method_declaration (m, header_file); - } - - var function = new CCodeFunction (get_ccode_real_name (m)); - - generate_cparameters (m, cfile, function); - - // generate *_real_* functions for virtual methods - if (!m.is_abstract) { - if (m.base_method != null || m.base_interface_method != null) { - // declare *_real_* function - function.modifiers |= CCodeModifiers.STATIC; - cfile.add_function_declaration (function); - } else if (m.is_internal_symbol ()) { - function.modifiers |= CCodeModifiers.STATIC; - } - - if (m.body != null) { - push_function (function); - - if (context.module_init_method == m) { - add_module_init (); - } - - if (m.closure) { - // add variables for parent closure blocks - // as closures only have one parameter for the innermost closure block - var closure_block = current_closure_block; - int block_id = get_block_id (closure_block); - while (true) { - var parent_closure_block = next_closure_block (closure_block.parent_symbol); - if (parent_closure_block == null) { - break; - } - int parent_block_id = get_block_id (parent_closure_block); - - var parent_data = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id)); - var cdecl = new CCodeDeclaration ("Block%dData*".printf (parent_block_id)); - cdecl.add_declarator (new CCodeVariableDeclarator ("_data%d_".printf (parent_block_id), parent_data)); - - ccode.add_statement (cdecl); - - closure_block = parent_closure_block; - block_id = parent_block_id; - } - - // add self variable for closures - // as closures have block data parameter - if (m.binding == MemberBinding.INSTANCE) { - var cself = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "this"); - var cdecl = new CCodeDeclaration ("%s *".printf (get_ccode_name (current_class))); - cdecl.add_declarator (new CCodeVariableDeclarator ("this", cself)); - - ccode.add_statement (cdecl); - } - } - foreach (Parameter param in m.get_parameters ()) { - if (param.ellipsis) { - break; - } - - var t = param.variable_type.data_type; - if (t != null && t.is_reference_type ()) { - if (param.direction == ParameterDirection.OUT) { - // ensure that the passed reference for output parameter is cleared - var a = new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (param.name)), new CCodeConstant ("NULL")); - var cblock = new CCodeBlock (); - cblock.add_statement (new CCodeExpressionStatement (a)); - - var condition = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier (param.name), new CCodeConstant ("NULL")); - var if_statement = new CCodeIfStatement (condition, cblock); - ccode.add_statement (if_statement); - } - } - } - - m.body.emit (this); - - if (!(m.return_type is VoidType) && !(m.return_type is GenericType)) { - var cdecl = new CCodeDeclaration (get_ccode_name (m.return_type)); - cdecl.add_declarator (new CCodeVariableDeclarator.zero ("result", default_value_for_type (m.return_type, true))); - ccode.add_statement (cdecl); - - ccode.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result"))); - } - - var st = m.parent_symbol as Struct; - if (m is CreationMethod && st != null && (st.is_boolean_type () || st.is_integer_type () || st.is_floating_type ())) { - var cdecl = new CCodeDeclaration (get_ccode_name (st)); - cdecl.add_declarator (new CCodeVariableDeclarator ("this", new CCodeConstant ("0"))); - ccode.add_statement (cdecl); - - ccode.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("this"))); - } - - cfile.add_function (function); - } - } - - if (m.is_abstract || m.is_virtual) { - generate_class_declaration ((Class) object_class, cfile); - - var vfunc = new CCodeFunction (get_ccode_name (m), (m.return_type is GenericType) ? "void" : get_ccode_name (m.return_type)); - vfunc.block = new CCodeBlock (); - - vfunc.add_parameter (new CCodeParameter ("this", "%s *".printf (get_ccode_name (m.parent_symbol)))); - foreach (TypeParameter type_param in m.get_type_parameters ()) { - vfunc.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType*")); - } - foreach (Parameter param in m.get_parameters ()) { - string ctypename = get_ccode_name (param.variable_type); - if (param.direction != ParameterDirection.IN) { - ctypename += "*"; - } - vfunc.add_parameter (new CCodeParameter (param.name, ctypename)); - } - if (m.return_type is GenericType) { - vfunc.add_parameter (new CCodeParameter ("result", "void *")); - } - - if (m.get_full_name () == "any.equals") { - // make this null-safe - var null_block = new CCodeBlock (); - null_block.add_statement (new CCodeReturnStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("other")))); - vfunc.block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("this")), null_block)); - } else if (m.get_full_name () == "any.hash") { - // make this null-safe - var null_block = new CCodeBlock (); - null_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("0"))); - vfunc.block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("this")), null_block)); - } else if (m.get_full_name () == "any.to_string") { - // make this null-safe - var null_string = new CCodeFunctionCall (new CCodeIdentifier ("string_create_from_cstring")); - null_string.add_argument (new CCodeConstant ("\"(null)\"")); - var null_block = new CCodeBlock (); - null_block.add_statement (new CCodeReturnStatement (null_string)); - vfunc.block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("this")), null_block)); - } - - var vcast = get_type_private_from_type ((ObjectTypeSymbol) m.parent_symbol, get_type_from_instance (new CCodeIdentifier ("this"))); - - var vcall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, get_ccode_vfunc_name (m))); - vcall.add_argument (new CCodeIdentifier ("this")); - foreach (TypeParameter type_param in m.get_type_parameters ()) { - vcall.add_argument (new CCodeIdentifier ("%s_type".printf (type_param.name.down ()))); - } - foreach (Parameter param in m.get_parameters ()) { - vcall.add_argument (new CCodeIdentifier (param.name)); - } - if (m.return_type is GenericType) { - vcall.add_argument (new CCodeIdentifier ("result")); - } - - if (m.return_type is VoidType || m.return_type is GenericType) { - vfunc.block.add_statement (new CCodeExpressionStatement (vcall)); - } else { - vfunc.block.add_statement (new CCodeReturnStatement (vcall)); - } - - cfile.add_function (vfunc); - - - vfunc = new CCodeFunction ("%sbase_%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), m.name), (m.return_type is GenericType) ? "void" : get_ccode_name (m.return_type)); - vfunc.block = new CCodeBlock (); - - vfunc.add_parameter (new CCodeParameter ("base_type", "DovaType *")); - vfunc.add_parameter (new CCodeParameter ("this", "%s *".printf (get_ccode_name (m.parent_symbol)))); - foreach (TypeParameter type_param in m.get_type_parameters ()) { - vfunc.add_parameter (new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType*")); - } - foreach (Parameter param in m.get_parameters ()) { - string ctypename = get_ccode_name (param.variable_type); - if (param.direction != ParameterDirection.IN) { - ctypename += "*"; - } - vfunc.add_parameter (new CCodeParameter (param.name, ctypename)); - } - if (m.return_type is GenericType) { - vfunc.add_parameter (new CCodeParameter ("result", "void *")); - } - - var base_type = new CCodeIdentifier ("base_type"); - - vcast = get_type_private_from_type ((ObjectTypeSymbol) m.parent_symbol, base_type); - - vcall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, get_ccode_vfunc_name (m))); - vcall.add_argument (new CCodeIdentifier ("this")); - foreach (TypeParameter type_param in m.get_type_parameters ()) { - vcall.add_argument (new CCodeIdentifier ("%s_type".printf (type_param.name.down ()))); - } - foreach (Parameter param in m.get_parameters ()) { - vcall.add_argument (new CCodeIdentifier (param.name)); - } - if (m.return_type is GenericType) { - vcall.add_argument (new CCodeIdentifier ("result")); - } - - if (m.return_type is VoidType || m.return_type is GenericType) { - vfunc.block.add_statement (new CCodeExpressionStatement (vcall)); - } else { - vfunc.block.add_statement (new CCodeReturnStatement (vcall)); - } - - cfile.add_function (vfunc); - - - string param_list = "(%s *this".printf (get_ccode_name (m.parent_symbol)); - foreach (var param in m.get_parameters ()) { - param_list += ", "; - param_list += get_ccode_name (param.variable_type); - } - if (m.return_type is GenericType) { - param_list += ", void *"; - } - param_list += ")"; - - var override_func = new CCodeFunction ("%soverride_%s".printf (get_ccode_lower_case_prefix (m.parent_symbol), m.name)); - override_func.add_parameter (new CCodeParameter ("type", "DovaType *")); - override_func.add_parameter (new CCodeParameter ("(*function) %s".printf (param_list), (m.return_type is GenericType) ? "void" : get_ccode_name (m.return_type))); - override_func.block = new CCodeBlock (); - - vcast = get_type_private_from_type ((ObjectTypeSymbol) m.parent_symbol, new CCodeIdentifier ("type")); - - override_func.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (vcast, m.name), new CCodeIdentifier ("function")))); - - cfile.add_function (override_func); - } - - pop_context (); - - if (m.entry_point) { - generate_type_declaration (new StructValueType (array_struct), cfile); - - // m is possible entry point, add appropriate startup code - var cmain = new CCodeFunction ("main", "int"); - cmain.line = function.line; - cmain.add_parameter (new CCodeParameter ("argc", "int")); - cmain.add_parameter (new CCodeParameter ("argv", "char **")); - - push_function (cmain); - - var dova_init_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_init")); - dova_init_call.add_argument (new CCodeIdentifier ("argc")); - dova_init_call.add_argument (new CCodeIdentifier ("argv")); - ccode.add_statement (new CCodeExpressionStatement (dova_init_call)); - - add_module_init (); - - var cdecl = new CCodeDeclaration ("int"); - cdecl.add_declarator (new CCodeVariableDeclarator ("result", new CCodeConstant ("0"))); - ccode.add_statement (cdecl); - - var main_call = new CCodeFunctionCall (new CCodeIdentifier (function.name)); - - if (m.get_parameters ().size == 1) { - // create Dova array from C array - // should be replaced by Dova list - var array_creation = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_create")); - array_creation.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("string_type_get"))); - array_creation.add_argument (new CCodeIdentifier ("argc")); - - cdecl = new CCodeDeclaration ("DovaArray"); - cdecl.add_declarator (new CCodeVariableDeclarator ("args", array_creation)); - ccode.add_statement (cdecl); - - var array_data = new CCodeMemberAccess (new CCodeIdentifier ("args"), "data"); - - cdecl = new CCodeDeclaration ("string_t*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("args_data", array_data)); - ccode.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("int"); - cdecl.add_declarator (new CCodeVariableDeclarator ("argi")); - ccode.add_statement (cdecl); - - var string_creation = new CCodeFunctionCall (new CCodeIdentifier ("string_create_from_cstring")); - string_creation.add_argument (new CCodeElementAccess (new CCodeIdentifier ("argv"), new CCodeIdentifier ("argi"))); - - var loop_block = new CCodeBlock (); - loop_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeElementAccess (new CCodeIdentifier ("args_data"), new CCodeIdentifier ("argi")), string_creation))); - - var for_stmt = new CCodeForStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("argi"), new CCodeIdentifier ("argc")), loop_block); - for_stmt.add_initializer (new CCodeAssignment (new CCodeIdentifier ("argi"), new CCodeConstant ("0"))); - for_stmt.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("argi"))); - ccode.add_statement (for_stmt); - - main_call.add_argument (new CCodeIdentifier ("args")); - } - - if (m.return_type is VoidType) { - // method returns void, always use 0 as exit code - var main_stmt = new CCodeExpressionStatement (main_call); - main_stmt.line = cmain.line; - ccode.add_statement (main_stmt); - } else { - var main_stmt = new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), main_call)); - main_stmt.line = cmain.line; - ccode.add_statement (main_stmt); - } - - var ret_stmt = new CCodeReturnStatement (new CCodeIdentifier ("result")); - ret_stmt.line = cmain.line; - ccode.add_statement (ret_stmt); - - pop_function (); - - cfile.add_function (cmain); - } - } - - public override void visit_creation_method (CreationMethod m) { - bool visible = !m.is_internal_symbol (); - - visit_method (m); - - DataType creturn_type; - if (current_type_symbol is Class) { - creturn_type = new ObjectType (current_class); - } else { - creturn_type = new VoidType (); - } - - // do not generate _new functions for creation methods of abstract classes - if (current_type_symbol is Class && !current_class.is_abstract) { - var vfunc = new CCodeFunction (get_ccode_name (m)); - - var vblock = new CCodeBlock (); - - var cdecl = new CCodeDeclaration ("%s *".printf (get_ccode_name (current_type_symbol))); - cdecl.add_declarator (new CCodeVariableDeclarator ("this")); - vblock.add_statement (cdecl); - - var type_get = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_lower_case_name (current_class) + "_type_get")); - foreach (var type_param in current_class.get_type_parameters ()) { - type_get.add_argument (new CCodeIdentifier ("%s_type".printf (type_param.name.down ()))); - } - - var alloc_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_alloc")); - alloc_call.add_argument (type_get); - vblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("this"), new CCodeCastExpression (alloc_call, "%s *".printf (get_ccode_name (current_type_symbol)))))); - - // allocate memory for fields of generic types - // this is only a temporary measure until this can be allocated inline at the end of the instance - // this also won't work for subclasses of classes that have fields of generic types - foreach (var f in current_class.get_fields ()) { - if (f.binding != MemberBinding.INSTANCE || !(f.variable_type is GenericType)) { - continue; - } - - var generic_type = (GenericType) f.variable_type; - var type_get_value_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_value_size")); - type_get_value_size.add_argument (new CCodeIdentifier ("%s_type".printf (generic_type.type_parameter.name.down ()))); - - var calloc_call = new CCodeFunctionCall (new CCodeIdentifier ("calloc")); - calloc_call.add_argument (new CCodeConstant ("1")); - calloc_call.add_argument (type_get_value_size); - var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (get_ccode_upper_case_name (current_class, null)))); - priv_call.add_argument (new CCodeIdentifier ("this")); - - vblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (priv_call, f.name), calloc_call))); - } - - var vcall = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_real_name (m))); - vcall.add_argument (new CCodeIdentifier ("this")); - vblock.add_statement (new CCodeExpressionStatement (vcall)); - - generate_cparameters (m, cfile, vfunc, null, vcall); - CCodeStatement cstmt = new CCodeReturnStatement (new CCodeIdentifier ("this")); - cstmt.line = vfunc.line; - vblock.add_statement (cstmt); - - if (!visible) { - vfunc.modifiers |= CCodeModifiers.STATIC; - } - - cfile.add_function_declaration (vfunc); - - vfunc.block = vblock; - - cfile.add_function (vfunc); - } - } - - private TypeSymbol? find_parent_type (Symbol sym) { - while (sym != null) { - if (sym is TypeSymbol) { - return (TypeSymbol) sym; - } - sym = sym.parent_symbol; - } - return null; - } - - public override void generate_cparameters (Method m, CCodeFile decl_space, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, CCodeFunctionCall? vcall = null) { - CCodeParameter instance_param = null; - if (m.closure) { - var closure_block = current_closure_block; - int block_id = get_block_id (closure_block); - instance_param = new CCodeParameter ("_data%d_".printf (block_id), "Block%dData*".printf (block_id)); - } else if (m.parent_symbol is Class && m is CreationMethod) { - if (vcall == null) { - instance_param = new CCodeParameter ("this", get_ccode_name (((Class) m.parent_symbol)) + "*"); - } - } else if (m.binding == MemberBinding.INSTANCE || (m.parent_symbol is Struct && m is CreationMethod)) { - TypeSymbol parent_type = find_parent_type (m); - var this_type = get_data_type_for_symbol (parent_type); - - generate_type_declaration (this_type, decl_space); - - if (m.base_interface_method != null && !m.is_abstract && !m.is_virtual) { - var base_type = new ObjectType ((Interface) m.base_interface_method.parent_symbol); - instance_param = new CCodeParameter ("this", get_ccode_name (base_type)); - } else if (m.overrides) { - var base_type = new ObjectType ((Class) m.base_method.parent_symbol); - generate_type_declaration (base_type, decl_space); - instance_param = new CCodeParameter ("this", get_ccode_name (base_type)); - } else { - if (m.parent_symbol is Struct && m is CreationMethod) { - var st = (Struct) m.parent_symbol; - if (st.is_boolean_type () || st.is_integer_type () || st.is_floating_type ()) { - // use return value - } else { - instance_param = new CCodeParameter ("*this", get_ccode_name (this_type)); - } - } else { - instance_param = new CCodeParameter ("this", get_ccode_name (this_type)); - } - } - } - if (instance_param != null) { - func.add_parameter (instance_param); - if (vdeclarator != null) { - vdeclarator.add_parameter (instance_param); - } - } - - if (m is CreationMethod) { - generate_class_declaration ((Class) type_class, decl_space); - - if (m.parent_symbol is Class) { - var cl = (Class) m.parent_symbol; - foreach (TypeParameter type_param in cl.get_type_parameters ()) { - var cparam = new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType*"); - if (vcall != null) { - func.add_parameter (cparam); - } - } - } - } else { - foreach (TypeParameter type_param in m.get_type_parameters ()) { - var cparam = new CCodeParameter ("%s_type".printf (type_param.name.down ()), "DovaType*"); - func.add_parameter (cparam); - if (vdeclarator != null) { - vdeclarator.add_parameter (cparam); - } - if (vcall != null) { - vcall.add_argument (new CCodeIdentifier ("%s_type".printf (type_param.name.down ()))); - } - } - } - - foreach (Parameter param in m.get_parameters ()) { - CCodeParameter cparam; - if (!param.ellipsis) { - string ctypename = get_ccode_name (param.variable_type); - - generate_type_declaration (param.variable_type, decl_space); - - if (param.direction != ParameterDirection.IN && !(param.variable_type is GenericType)) { - ctypename += "*"; - } - - cparam = new CCodeParameter (get_variable_cname (param.name), ctypename); - } else { - cparam = new CCodeParameter.with_ellipsis (); - } - - func.add_parameter (cparam); - if (vdeclarator != null) { - vdeclarator.add_parameter (cparam); - } - if (vcall != null) { - if (param.name != null) { - vcall.add_argument (get_variable_cexpression (param.name)); - } - } - } - - if (m.parent_symbol is Class && m is CreationMethod && vcall != null) { - func.return_type = get_ccode_name (((Class) m.parent_symbol)) + "*"; - } else { - if (m.return_type is GenericType) { - func.add_parameter (new CCodeParameter ("result", "void *")); - if (vdeclarator != null) { - vdeclarator.add_parameter (new CCodeParameter ("result", "void *")); - } - } else { - var st = m.parent_symbol as Struct; - if (m is CreationMethod && st != null && (st.is_boolean_type () || st.is_integer_type () || st.is_floating_type ())) { - func.return_type = get_ccode_name (st); - } else { - func.return_type = get_ccode_name (m.return_type); - } - } - - generate_type_declaration (m.return_type, decl_space); - } - } - - public override void visit_element_access (ElementAccess expr) { - var array_type = expr.container.value_type as ArrayType; - if (array_type != null) { - // access to element in an array - - expr.accept_children (this); - - List indices = expr.get_indices (); - var cindex = get_cvalue (indices[0]); - - if (array_type.inline_allocated) { - if (array_type.element_type is GenericType) { - // generic array - // calculate offset in bytes based on value size - var value_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_value_size")); - value_size.add_argument (get_type_id_expression (array_type.element_type)); - set_cvalue (expr, new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeCastExpression (get_cvalue (expr.container), "char*"), new CCodeBinaryExpression (CCodeBinaryOperator.MUL, value_size, cindex))); - } else { - set_cvalue (expr, new CCodeElementAccess (get_cvalue (expr.container), cindex)); - } - } else { - var ccontainer = new CCodeMemberAccess (get_cvalue (expr.container), "data"); - - if (array_type.element_type is GenericType) { - // generic array - // calculate offset in bytes based on value size - var value_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_value_size")); - value_size.add_argument (get_type_id_expression (array_type.element_type)); - set_cvalue (expr, new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeCastExpression (ccontainer, "char*"), new CCodeBinaryExpression (CCodeBinaryOperator.MUL, value_size, cindex))); - } else { - set_cvalue (expr, new CCodeElementAccess (new CCodeCastExpression (ccontainer, "%s*".printf (get_ccode_name (array_type.element_type))), cindex)); - } - } - - } else { - base.visit_element_access (expr); - } - } - - void add_module_init () { - foreach (var field in static_fields) { - field.initializer.emit (this); - - var lhs = new CCodeIdentifier (get_ccode_name (field)); - var rhs = get_cvalue (field.initializer); - - ccode.add_assignment (lhs, rhs); - } - } -} diff --git a/codegen/valadovastructmodule.vala b/codegen/valadovastructmodule.vala deleted file mode 100644 index ba3d49ded..000000000 --- a/codegen/valadovastructmodule.vala +++ /dev/null @@ -1,86 +0,0 @@ -/* valadovastructmodule.vala - * - * Copyright (C) 2006-2009 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.1 of the License, or (at your option) any later version. - - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: - * Jürg Billeter - */ - -using GLib; - -public abstract class Vala.DovaStructModule : DovaBaseModule { - public override void generate_struct_declaration (Struct st, CCodeFile decl_space) { - if (add_symbol_declaration (decl_space, st, get_ccode_name (st))) { - return; - } - - if (st.base_struct != null) { - generate_struct_declaration (st.base_struct, decl_space); - - decl_space.add_type_declaration (new CCodeTypeDefinition (get_ccode_name (st.base_struct), new CCodeVariableDeclarator (get_ccode_name (st)))); - return; - } - - if (st.is_boolean_type ()) { - // typedef for boolean types - return; - } else if (st.is_integer_type ()) { - // typedef for integral types - return; - } else if (st.is_decimal_floating_type ()) { - // typedef for decimal floating types - return; - } else if (st.is_floating_type ()) { - // typedef for generic floating types - return; - } - - var instance_struct = new CCodeStruct ("_%s".printf (get_ccode_name (st))); - - foreach (Field f in st.get_fields ()) { - string field_ctype = get_ccode_name (f.variable_type); - if (f.is_volatile) { - field_ctype = "volatile " + field_ctype; - } - - if (f.binding == MemberBinding.INSTANCE) { - generate_type_declaration (f.variable_type, decl_space); - - instance_struct.add_field (field_ctype, get_ccode_name (f) + get_ccode_declarator_suffix (f.variable_type)); - } - } - - decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (get_ccode_name (st)), new CCodeVariableDeclarator (get_ccode_name (st)))); - - decl_space.add_type_definition (instance_struct); - } - - public override void visit_struct (Struct st) { - push_context (new EmitContext (st)); - - generate_struct_declaration (st, cfile); - - if (!st.is_internal_symbol ()) { - generate_struct_declaration (st, header_file); - } - - st.accept_children (this); - - pop_context (); - } -} - diff --git a/codegen/valadovavaluemodule.vala b/codegen/valadovavaluemodule.vala deleted file mode 100644 index f7ddd0474..000000000 --- a/codegen/valadovavaluemodule.vala +++ /dev/null @@ -1,726 +0,0 @@ -/* valadovavaluemodule.vala - * - * Copyright (C) 2009-2011 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.1 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 - */ - -public class Vala.DovaValueModule : DovaObjectModule { - public override void visit_creation_method (CreationMethod m) { - if (current_type_symbol is Class && - (current_class.base_class == null || - current_class.base_class.get_full_name () != "Dova.Value")) { - base.visit_creation_method (m); - return; - } - - visit_method (m); - } - - public override void generate_struct_declaration (Struct st, CCodeFile decl_space) { - base.generate_struct_declaration (st, decl_space); - - if (add_symbol_declaration (decl_space, st, get_ccode_copy_function (st))) { - return; - } - - generate_class_declaration (type_class, decl_space); - - var type_fun = new CCodeFunction ("%s_type_get".printf (get_ccode_lower_case_name (st)), "DovaType *"); - if (st.is_internal_symbol ()) { - type_fun.modifiers = CCodeModifiers.STATIC; - } - decl_space.add_function_declaration (type_fun); - - var type_init_fun = new CCodeFunction ("%s_type_init".printf (get_ccode_lower_case_name (st))); - type_init_fun.add_parameter (new CCodeParameter ("type", "DovaType *")); - if (st.is_internal_symbol ()) { - type_init_fun.modifiers = CCodeModifiers.STATIC; - } - decl_space.add_function_declaration (type_init_fun); - - var function = new CCodeFunction (get_ccode_copy_function (st), "void"); - if (st.is_internal_symbol ()) { - function.modifiers = CCodeModifiers.STATIC; - } - - function.add_parameter (new CCodeParameter ("dest", get_ccode_name (st) + "*")); - function.add_parameter (new CCodeParameter ("dest_index", "intptr_t")); - function.add_parameter (new CCodeParameter ("src", get_ccode_name (st) + "*")); - function.add_parameter (new CCodeParameter ("src_index", "intptr_t")); - - decl_space.add_function_declaration (function); - } - - public override void visit_struct (Struct st) { - base.visit_struct (st); - - var cdecl = new CCodeDeclaration ("intptr_t"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_%s_object_offset".printf (get_ccode_lower_case_name (st)), new CCodeConstant ("0"))); - cdecl.modifiers = CCodeModifiers.STATIC; - cfile.add_type_member_declaration (cdecl); - - string macro = "((%s *) (((char *) o) + _%s_object_offset))".printf (get_ccode_name (st), get_ccode_lower_case_name (st)); - cfile.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (get_ccode_upper_case_name (st, null)), macro)); - - - cdecl = new CCodeDeclaration ("DovaType *"); - cdecl.add_declarator (new CCodeVariableDeclarator ("%s_type".printf (get_ccode_lower_case_name (st)), new CCodeConstant ("NULL"))); - cdecl.modifiers = CCodeModifiers.STATIC; - cfile.add_type_member_declaration (cdecl); - - var type_fun = new CCodeFunction ("%s_type_get".printf (get_ccode_lower_case_name (st)), "DovaType *"); - type_fun.block = new CCodeBlock (); - - var type_init_block = new CCodeBlock (); - - generate_method_declaration ((Method) object_class.scope.lookup ("alloc"), cfile); - generate_property_accessor_declaration (((Property) type_class.scope.lookup ("base_type")).get_accessor, cfile); - generate_property_accessor_declaration (((Property) type_class.scope.lookup ("base_type")).set_accessor, cfile); - generate_property_accessor_declaration (((Property) type_class.scope.lookup ("object_size")).get_accessor, cfile); - generate_property_accessor_declaration (((Property) type_class.scope.lookup ("object_size")).set_accessor, cfile); - generate_property_accessor_declaration (((Property) type_class.scope.lookup ("type_size")).get_accessor, cfile); - generate_property_accessor_declaration (((Property) type_class.scope.lookup ("type_size")).set_accessor, cfile); - generate_property_accessor_declaration (((Property) type_class.scope.lookup ("value_size")).set_accessor, cfile); - - generate_class_declaration ((Class) context.root.scope.lookup ("Dova").scope.lookup ("Value"), cfile); - - var base_type = new CCodeFunctionCall (new CCodeIdentifier ("dova_value_type_get")); - - var base_type_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_type_size")); - base_type_size.add_argument (base_type); - - var calloc_call = new CCodeFunctionCall (new CCodeIdentifier ("calloc")); - calloc_call.add_argument (new CCodeConstant ("1")); - calloc_call.add_argument (base_type_size); - - type_init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st))), calloc_call))); - - generate_class_declaration ((Class) object_class, cfile); - - type_init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeCastExpression (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st))), "DovaObject *"), "type"), new CCodeFunctionCall (new CCodeIdentifier ("dova_type_type_get"))))); - - var set_base_type = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_base_type")); - set_base_type.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st)))); - set_base_type.add_argument (base_type); - type_init_block.add_statement (new CCodeExpressionStatement (set_base_type)); - - var base_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_object_size")); - base_size.add_argument (base_type); - - type_init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_%s_object_offset".printf (get_ccode_lower_case_name (st))), base_size))); - - var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof")); - sizeof_call.add_argument (new CCodeIdentifier (get_ccode_name (st))); - var set_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_object_size")); - set_size.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st)))); - set_size.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, base_size, sizeof_call)); - type_init_block.add_statement (new CCodeExpressionStatement (set_size)); - - set_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_size")); - set_size.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st)))); - set_size.add_argument (sizeof_call); - type_init_block.add_statement (new CCodeExpressionStatement (set_size)); - - set_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_type_size")); - set_size.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st)))); - set_size.add_argument (base_type_size); - type_init_block.add_statement (new CCodeExpressionStatement (set_size)); - - var type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_type_init".printf (get_ccode_lower_case_name (st)))); - type_init_call.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st)))); - type_init_block.add_statement (new CCodeExpressionStatement (type_init_call)); - - // workaround: set value_size again as it is currently overwritten by dova_object_type_init - set_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_size")); - set_size.add_argument (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st)))); - set_size.add_argument (sizeof_call); - type_init_block.add_statement (new CCodeExpressionStatement (set_size)); - - type_fun.block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st)))), type_init_block)); - - type_fun.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("%s_type".printf (get_ccode_lower_case_name (st))))); - - cfile.add_function (type_fun); - - var type_init_fun = new CCodeFunction ("%s_type_init".printf (get_ccode_lower_case_name (st))); - type_init_fun.add_parameter (new CCodeParameter ("type", "DovaType *")); - type_init_fun.block = new CCodeBlock (); - - type_init_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_value_type_init")); - type_init_call.add_argument (new CCodeIdentifier ("type")); - type_init_fun.block.add_statement (new CCodeExpressionStatement (type_init_call)); - - declare_set_value_copy_function (cfile); - - var value_copy_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_copy")); - value_copy_call.add_argument (new CCodeIdentifier ("type")); - value_copy_call.add_argument (new CCodeCastExpression (new CCodeIdentifier ("%s_copy".printf (get_ccode_lower_case_name (st))), "void (*)(void *, intptr_t, void *, intptr_t)")); - type_init_fun.block.add_statement (new CCodeExpressionStatement (value_copy_call)); - - if (st.scope.lookup ("equals") is Method) { - var value_equals_fun = new CCodeFunction ("%s_value_equals".printf (get_ccode_lower_case_name (st)), "bool"); - value_equals_fun.modifiers = CCodeModifiers.STATIC; - value_equals_fun.add_parameter (new CCodeParameter ("value", get_ccode_name (st) + "*")); - value_equals_fun.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - value_equals_fun.add_parameter (new CCodeParameter ("other", get_ccode_name (st) + "*")); - value_equals_fun.add_parameter (new CCodeParameter ("other_index", "intptr_t")); - value_equals_fun.block = new CCodeBlock (); - var val = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("value"), new CCodeIdentifier ("value_index")); - var other = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("other"), new CCodeIdentifier ("other_index")); - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_equals".printf (get_ccode_lower_case_name (st)))); - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, val)); - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, other)); - value_equals_fun.block.add_statement (new CCodeReturnStatement (ccall)); - cfile.add_function (value_equals_fun); - - declare_set_value_equals_function (cfile); - - var value_equals_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_equals")); - value_equals_call.add_argument (new CCodeIdentifier ("type")); - value_equals_call.add_argument (new CCodeCastExpression (new CCodeIdentifier ("%s_value_equals".printf (get_ccode_lower_case_name (st))), "bool (*)(void *, intptr_t, void *, intptr_t)")); - type_init_fun.block.add_statement (new CCodeExpressionStatement (value_equals_call)); - } - - if (st.scope.lookup ("hash") is Method) { - var value_hash_fun = new CCodeFunction ("%s_value_hash".printf (get_ccode_lower_case_name (st)), "uintptr_t"); - value_hash_fun.modifiers = CCodeModifiers.STATIC; - value_hash_fun.add_parameter (new CCodeParameter ("value", get_ccode_name (st) + "*")); - value_hash_fun.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - value_hash_fun.block = new CCodeBlock (); - var val = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("value"), new CCodeIdentifier ("value_index")); - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_hash".printf (get_ccode_lower_case_name (st)))); - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, val)); - value_hash_fun.block.add_statement (new CCodeReturnStatement (ccall)); - cfile.add_function (value_hash_fun); - - declare_set_value_hash_function (cfile); - - var value_hash_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_hash")); - value_hash_call.add_argument (new CCodeIdentifier ("type")); - value_hash_call.add_argument (new CCodeCastExpression (new CCodeIdentifier ("%s_value_hash".printf (get_ccode_lower_case_name (st))), "uintptr_t (*)(void *, intptr_t)")); - type_init_fun.block.add_statement (new CCodeExpressionStatement (value_hash_call)); - } - - // generate method to box values - var value_to_any_fun = new CCodeFunction ("%s_value_to_any".printf (get_ccode_lower_case_name (st)), "DovaObject*"); - value_to_any_fun.modifiers = CCodeModifiers.STATIC; - value_to_any_fun.add_parameter (new CCodeParameter ("value", "void *")); - value_to_any_fun.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - value_to_any_fun.block = new CCodeBlock (); - var alloc_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_alloc")); - alloc_call.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (get_ccode_lower_case_name (st))))); - cdecl = new CCodeDeclaration ("DovaObject *"); - cdecl.add_declarator (new CCodeVariableDeclarator ("result", alloc_call)); - value_to_any_fun.block.add_statement (cdecl); - var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (get_ccode_upper_case_name (st, null)))); - priv_call.add_argument (new CCodeIdentifier ("result")); - var copy_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_copy".printf (get_ccode_lower_case_name (st)))); - copy_call.add_argument (priv_call); - copy_call.add_argument (new CCodeConstant ("0")); - copy_call.add_argument (new CCodeIdentifier ("value")); - copy_call.add_argument (new CCodeIdentifier ("value_index")); - value_to_any_fun.block.add_statement (new CCodeExpressionStatement (copy_call)); - value_to_any_fun.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result"))); - cfile.add_function (value_to_any_fun); - - declare_set_value_to_any_function (cfile); - - var value_to_any_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_to_any")); - value_to_any_call.add_argument (new CCodeIdentifier ("type")); - value_to_any_call.add_argument (new CCodeIdentifier ("%s_value_to_any".printf (get_ccode_lower_case_name (st)))); - type_init_fun.block.add_statement (new CCodeExpressionStatement (value_to_any_call)); - - // generate method to unbox values - var value_from_any_fun = new CCodeFunction ("%s_value_from_any".printf (get_ccode_lower_case_name (st))); - value_from_any_fun.modifiers = CCodeModifiers.STATIC; - value_from_any_fun.add_parameter (new CCodeParameter ("any_", "any *")); - value_from_any_fun.add_parameter (new CCodeParameter ("value", get_ccode_name (st) + "*")); - value_from_any_fun.add_parameter (new CCodeParameter ("value_index", "intptr_t")); - value_from_any_fun.block = new CCodeBlock (); - priv_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (get_ccode_upper_case_name (st, null)))); - priv_call.add_argument (new CCodeIdentifier ("any_")); - copy_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_copy".printf (get_ccode_lower_case_name (st)))); - copy_call.add_argument (new CCodeIdentifier ("value")); - copy_call.add_argument (new CCodeIdentifier ("value_index")); - copy_call.add_argument (priv_call); - copy_call.add_argument (new CCodeConstant ("0")); - value_from_any_fun.block.add_statement (new CCodeExpressionStatement (copy_call)); - cfile.add_function (value_from_any_fun); - - declare_set_value_from_any_function (cfile); - - var value_from_any_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_set_value_from_any")); - value_from_any_call.add_argument (new CCodeIdentifier ("type")); - value_from_any_call.add_argument (new CCodeIdentifier ("%s_value_from_any".printf (get_ccode_lower_case_name (st)))); - type_init_fun.block.add_statement (new CCodeExpressionStatement (value_from_any_call)); - - cfile.add_function (type_init_fun); - - add_struct_copy_function (st); - } - - void add_struct_copy_function (Struct st) { - var function = new CCodeFunction (get_ccode_copy_function (st), "void"); - if (st.is_internal_symbol ()) { - function.modifiers = CCodeModifiers.STATIC; - } - - function.add_parameter (new CCodeParameter ("dest", get_ccode_name (st) + "*")); - function.add_parameter (new CCodeParameter ("dest_index", "intptr_t")); - function.add_parameter (new CCodeParameter ("src", get_ccode_name (st) + "*")); - function.add_parameter (new CCodeParameter ("src_index", "intptr_t")); - - var cblock = new CCodeBlock (); - var cfrag = new CCodeFragment (); - cblock.add_statement (cfrag); - - var dest = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("dest"), new CCodeIdentifier ("dest_index")); - var src = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("src"), new CCodeIdentifier ("src_index")); - - foreach (var f in st.get_fields ()) { - if (f.binding == MemberBinding.INSTANCE) { - var field = new CCodeMemberAccess.pointer (dest, f.name); - - var array_type = f.variable_type as ArrayType; - if (array_type != null && array_type.fixed_length) { - for (int i = 0; i < array_type.length; i++) { - var element = new CCodeElementAccess (field, new CCodeConstant (i.to_string ())); - - if (requires_destroy (array_type.element_type)) { - cblock.add_statement (new CCodeExpressionStatement (get_unref_expression (element, array_type.element_type))); - } - } - continue; - } - - if (requires_destroy (f.variable_type)) { - var this_access = new MemberAccess.simple ("this"); - this_access.value_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol); - set_cvalue (this_access, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, dest)); - var ma = new MemberAccess (this_access, f.name); - ma.symbol_reference = f; - ma.value_type = f.variable_type.copy (); - cblock.add_statement (new CCodeExpressionStatement (get_unref_expression (field, f.variable_type, ma))); - } - } - } - - var copy_block = new CCodeBlock (); - - if (st.get_fields ().size == 0) { - copy_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, dest), new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, src)))); - } else { - foreach (var f in st.get_fields ()) { - if (f.binding == MemberBinding.INSTANCE) { - CCodeExpression copy = new CCodeMemberAccess.pointer (src, f.name); - var dest_field = new CCodeMemberAccess.pointer (dest, f.name); - - var array_type = f.variable_type as ArrayType; - if (array_type != null && array_type.fixed_length) { - for (int i = 0; i < array_type.length; i++) { - CCodeExpression copy_element = new CCodeElementAccess (copy, new CCodeConstant (i.to_string ())); - var dest_field_element = new CCodeElementAccess (dest_field, new CCodeConstant (i.to_string ())); - - if (requires_copy (array_type.element_type)) { - copy_element = get_ref_cexpression (array_type.element_type, copy_element, null, f); - } - - copy_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (dest_field_element, copy_element))); - } - continue; - } - - if (requires_copy (f.variable_type)) { - var this_access = new MemberAccess.simple ("this"); - this_access.value_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol); - set_cvalue (this_access, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, src)); - var ma = new MemberAccess (this_access, f.name); - ma.symbol_reference = f; - copy = get_ref_cexpression (f.variable_type, copy, ma, f); - } - - copy_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (dest_field, copy))); - } - } - } - - cblock.add_statement (new CCodeIfStatement (new CCodeIdentifier ("src"), copy_block)); - - function.block = cblock; - - cfile.add_function (function); - } - - public override void visit_assignment (Assignment assignment) { - var generic_type = assignment.left.value_type as GenericType; - if (generic_type == null) { - base.visit_assignment (assignment); - return; - } - - var dest = assignment.left; - CCodeExpression cdest; - CCodeExpression dest_index = new CCodeConstant ("0"); - var src = assignment.right; - CCodeExpression csrc; - CCodeExpression src_index = new CCodeConstant ("0"); - - if (src is NullLiteral) { - // TODO destroy dest - set_cvalue (assignment, new CCodeConstant ("0")); - return; - } - - var dest_ea = dest as ElementAccess; - var src_ea = src as ElementAccess; - - if (dest_ea != null) { - dest = dest_ea.container; - - var array_type = dest.value_type as ArrayType; - if (array_type != null && !array_type.inline_allocated) { - cdest = new CCodeMemberAccess ((CCodeExpression) get_ccodenode (dest), "data"); - } else { - cdest = (CCodeExpression) get_ccodenode (dest); - } - dest_index = (CCodeExpression) get_ccodenode (dest_ea.get_indices ().get (0)); - } else { - cdest = (CCodeExpression) get_ccodenode (dest); - } - - if (src_ea != null) { - src = src_ea.container; - - var array_type = src.value_type as ArrayType; - if (array_type != null && !array_type.inline_allocated) { - csrc = new CCodeMemberAccess ((CCodeExpression) get_ccodenode (src), "data"); - } else { - csrc = (CCodeExpression) get_ccodenode (src); - } - src_index = (CCodeExpression) get_ccodenode (src_ea.get_indices ().get (0)); - } else { - csrc = (CCodeExpression) get_ccodenode (src); - } - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_value_copy")); - if (generic_type.type_parameter.parent_symbol is TypeSymbol) { - // generic type - ccall.add_argument (new CCodeMemberAccess.pointer (get_type_private_from_type ((ObjectTypeSymbol) generic_type.type_parameter.parent_symbol, new CCodeMemberAccess.pointer (new CCodeIdentifier ("this"), "type")), "%s_type".printf (generic_type.type_parameter.name.down ()))); - } else { - // generic method - ccall.add_argument (new CCodeIdentifier ("%s_type".printf (generic_type.type_parameter.name.down ()))); - } - ccall.add_argument (cdest); - ccall.add_argument (dest_index); - ccall.add_argument (csrc); - ccall.add_argument (src_index); - set_cvalue (assignment, ccall); - } - - public override void store_variable (Variable variable, TargetValue lvalue, TargetValue value, bool initializer) { - var generic_type = lvalue.value_type as GenericType; - if (generic_type == null) { - base.store_variable (variable, lvalue, value, initializer); - return; - } - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_value_copy")); - if (generic_type.type_parameter.parent_symbol is TypeSymbol) { - // generic type - ccall.add_argument (new CCodeMemberAccess.pointer (get_type_private_from_type ((ObjectTypeSymbol) generic_type.type_parameter.parent_symbol, new CCodeMemberAccess.pointer (new CCodeIdentifier ("this"), "type")), "%s_type".printf (generic_type.type_parameter.name.down ()))); - } else { - // generic method - ccall.add_argument (new CCodeIdentifier ("%s_type".printf (generic_type.type_parameter.name.down ()))); - } - ccall.add_argument (get_cvalue_ (lvalue)); - ccall.add_argument (new CCodeConstant ("0")); - ccall.add_argument (get_cvalue_ (value)); - ccall.add_argument (new CCodeConstant ("0")); - - ccode.add_expression (ccall); - } - - public override void visit_binary_expression (BinaryExpression expr) { - var generic_type = expr.left.value_type as GenericType; - if (generic_type == null) { - base.visit_binary_expression (expr); - return; - } - - CCodeExpression cleft; - CCodeExpression left_index = new CCodeConstant ("0"); - CCodeExpression cright; - CCodeExpression right_index = new CCodeConstant ("0"); - - var left_ea = expr.left as ElementAccess; - var right_ea = expr.right as ElementAccess; - - if (left_ea != null) { - cleft = new CCodeMemberAccess ((CCodeExpression) get_ccodenode (left_ea.container), "data"); - left_index = (CCodeExpression) get_ccodenode (left_ea.get_indices ().get (0)); - } else { - cleft = (CCodeExpression) get_ccodenode (expr.left); - } - - if (right_ea != null) { - cright = new CCodeMemberAccess ((CCodeExpression) get_ccodenode (right_ea.container), "data"); - right_index = (CCodeExpression) get_ccodenode (right_ea.get_indices ().get (0)); - } else { - cright = (CCodeExpression) get_ccodenode (expr.right); - } - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_value_equals")); - ccall.add_argument (get_type_id_expression (generic_type)); - ccall.add_argument (cleft); - ccall.add_argument (left_index); - ccall.add_argument (cright); - ccall.add_argument (right_index); - - if (expr.operator == BinaryOperator.EQUALITY) { - set_cvalue (expr, ccall); - } else { - set_cvalue (expr, new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, ccall)); - } - } - - public override void visit_method_call (MethodCall expr) { - var ma = expr.call as MemberAccess; - if (ma == null || ma.inner == null || !(ma.inner.value_type is GenericType)) { - base.visit_method_call (expr); - return; - } - - // handle method calls on generic types - - expr.accept_children (this); - - if (ma.member_name == "hash") { - var val = ma.inner; - CCodeExpression cval; - CCodeExpression val_index = new CCodeConstant ("0"); - - var val_ea = val as ElementAccess; - if (val_ea != null) { - val = val_ea.container; - - cval = new CCodeMemberAccess ((CCodeExpression) get_ccodenode (val), "data"); - val_index = (CCodeExpression) get_ccodenode (val_ea.get_indices ().get (0)); - } else { - cval = (CCodeExpression) get_ccodenode (val); - } - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_value_hash")); - ccall.add_argument (get_type_id_expression (ma.inner.value_type)); - ccall.add_argument (cval); - ccall.add_argument (val_index); - - set_cvalue (expr, ccall); - } - } - - public override void visit_list_literal (ListLiteral expr) { - CCodeExpression ptr; - int length = expr.get_expressions ().size; - - if (length == 0) { - ptr = new CCodeConstant ("NULL"); - } else { - var array_type = new ArrayType (expr.element_type, 1, expr.source_reference); - array_type.inline_allocated = true; - array_type.fixed_length = true; - array_type.length = length; - - var temp_var = get_temp_variable (array_type, true, expr); - var name_cnode = get_variable_cexpression (temp_var.name); - - emit_temp_var (temp_var); - - int i = 0; - foreach (Expression e in expr.get_expressions ()) { - ccode.add_assignment (new CCodeElementAccess (name_cnode, new CCodeConstant (i.to_string ())), get_cvalue (e)); - i++; - } - - ptr = name_cnode; - } - - var array_type = new ArrayType (expr.element_type, 1, expr.source_reference); - - var temp_var = get_temp_variable (array_type, true, expr); - var name_cnode = get_variable_cexpression (temp_var.name); - - emit_temp_var (temp_var); - - var array_init = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_init")); - array_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, name_cnode)); - array_init.add_argument (ptr); - array_init.add_argument (new CCodeConstant (length.to_string ())); - ccode.add_expression (array_init); - - var list_creation = new CCodeFunctionCall (new CCodeIdentifier ("dova_list_new")); - list_creation.add_argument (get_type_id_expression (expr.element_type)); - list_creation.add_argument (name_cnode); - - set_cvalue (expr, list_creation); - } - - public override void visit_set_literal (SetLiteral expr) { - var ce = new CCodeCommaExpression (); - int length = expr.get_expressions ().size; - - if (length == 0) { - ce.append_expression (new CCodeConstant ("NULL")); - } else { - var array_type = new ArrayType (expr.element_type, 1, expr.source_reference); - array_type.inline_allocated = true; - array_type.fixed_length = true; - array_type.length = length; - - var temp_var = get_temp_variable (array_type, true, expr); - var name_cnode = get_variable_cexpression (temp_var.name); - - emit_temp_var (temp_var); - - int i = 0; - foreach (Expression e in expr.get_expressions ()) { - ce.append_expression (new CCodeAssignment (new CCodeElementAccess (name_cnode, new CCodeConstant (i.to_string ())), get_cvalue (e))); - i++; - } - - ce.append_expression (name_cnode); - } - - var set_creation = new CCodeFunctionCall (new CCodeIdentifier ("dova_set_new")); - set_creation.add_argument (get_type_id_expression (expr.element_type)); - set_creation.add_argument (new CCodeConstant (length.to_string ())); - set_creation.add_argument (ce); - - set_cvalue (expr, set_creation); - } - - public override void visit_map_literal (MapLiteral expr) { - var key_ce = new CCodeCommaExpression (); - var value_ce = new CCodeCommaExpression (); - int length = expr.get_keys ().size; - - if (length == 0) { - key_ce.append_expression (new CCodeConstant ("NULL")); - value_ce.append_expression (new CCodeConstant ("NULL")); - } else { - var key_array_type = new ArrayType (expr.map_key_type, 1, expr.source_reference); - key_array_type.inline_allocated = true; - key_array_type.fixed_length = true; - key_array_type.length = length; - - var key_temp_var = get_temp_variable (key_array_type, true, expr); - var key_name_cnode = get_variable_cexpression (key_temp_var.name); - - emit_temp_var (key_temp_var); - - var value_array_type = new ArrayType (expr.map_value_type, 1, expr.source_reference); - value_array_type.inline_allocated = true; - value_array_type.fixed_length = true; - value_array_type.length = length; - - var value_temp_var = get_temp_variable (value_array_type, true, expr); - var value_name_cnode = get_variable_cexpression (value_temp_var.name); - - emit_temp_var (value_temp_var); - - for (int i = 0; i < length; i++) { - key_ce.append_expression (new CCodeAssignment (new CCodeElementAccess (key_name_cnode, new CCodeConstant (i.to_string ())), get_cvalue (expr.get_keys ().get (i)))); - value_ce.append_expression (new CCodeAssignment (new CCodeElementAccess (value_name_cnode, new CCodeConstant (i.to_string ())), get_cvalue (expr.get_values ().get (i)))); - } - - key_ce.append_expression (key_name_cnode); - value_ce.append_expression (value_name_cnode); - } - - var map_creation = new CCodeFunctionCall (new CCodeIdentifier ("dova_map_new")); - map_creation.add_argument (get_type_id_expression (expr.map_key_type)); - map_creation.add_argument (get_type_id_expression (expr.map_value_type)); - map_creation.add_argument (new CCodeConstant (length.to_string ())); - map_creation.add_argument (key_ce); - map_creation.add_argument (value_ce); - - set_cvalue (expr, map_creation); - } - - public override void visit_tuple (Tuple tuple) { - var type_array_type = new ArrayType (new PointerType (new VoidType ()), 1, tuple.source_reference); - type_array_type.inline_allocated = true; - type_array_type.fixed_length = true; - type_array_type.length = tuple.get_expressions ().size; - - var type_temp_var = get_temp_variable (type_array_type, true, tuple); - var type_name_cnode = get_variable_cexpression (type_temp_var.name); - emit_temp_var (type_temp_var); - - var array_type = new ArrayType (new PointerType (new VoidType ()), 1, tuple.source_reference); - array_type.inline_allocated = true; - array_type.fixed_length = true; - array_type.length = tuple.get_expressions ().size; - - var temp_var = get_temp_variable (array_type, true, tuple); - var name_cnode = get_variable_cexpression (temp_var.name); - emit_temp_var (temp_var); - - var type_ce = new CCodeCommaExpression (); - var ce = new CCodeCommaExpression (); - - int i = 0; - foreach (Expression e in tuple.get_expressions ()) { - var element_type = tuple.value_type.get_type_arguments ().get (i); - - type_ce.append_expression (new CCodeAssignment (new CCodeElementAccess (type_name_cnode, new CCodeConstant (i.to_string ())), get_type_id_expression (element_type))); - - var cexpr = get_cvalue (e); - - var unary = cexpr as CCodeUnaryExpression; - if (unary != null && unary.operator == CCodeUnaryOperator.POINTER_INDIRECTION) { - // *expr => expr - cexpr = unary.inner; - } else if (cexpr is CCodeIdentifier || cexpr is CCodeMemberAccess) { - cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr); - } else { - // if cexpr is e.g. a function call, we can't take the address of the expression - // tmp = expr, &tmp - - var element_temp_var = get_temp_variable (element_type); - emit_temp_var (element_temp_var); - ce.append_expression (new CCodeAssignment (get_variable_cexpression (element_temp_var.name), cexpr)); - cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (element_temp_var.name)); - } - - ce.append_expression (new CCodeAssignment (new CCodeElementAccess (name_cnode, new CCodeConstant (i.to_string ())), cexpr)); - - i++; - } - - type_ce.append_expression (type_name_cnode); - ce.append_expression (name_cnode); - - var tuple_creation = new CCodeFunctionCall (new CCodeIdentifier ("dova_tuple_new")); - tuple_creation.add_argument (new CCodeConstant (tuple.get_expressions ().size.to_string ())); - tuple_creation.add_argument (type_ce); - tuple_creation.add_argument (ce); - - set_cvalue (tuple, tuple_creation); - } -} diff --git a/compiler/valacompiler.vala b/compiler/valacompiler.vala index b0722eb2e..830c8b9eb 100644 --- a/compiler/valacompiler.vala +++ b/compiler/valacompiler.vala @@ -214,9 +214,6 @@ class Vala.Compiler { // default profile context.profile = Profile.GOBJECT; context.add_define ("GOBJECT"); - } else if (profile == "dova") { - context.profile = Profile.DOVA; - context.add_define ("DOVA"); } else { Report.error (null, "Unknown profile %s".printf (profile)); } @@ -264,11 +261,6 @@ class Vala.Compiler { context.add_external_package ("glib-2.0"); context.add_external_package ("gobject-2.0"); } - } else if (context.profile == Profile.DOVA) { - if (!nostdpkg) { - /* default package */ - context.add_external_package ("dova-core-0.1"); - } } if (packages != null) { @@ -292,8 +284,6 @@ class Vala.Compiler { if (context.profile == Profile.GOBJECT) { context.codegen = new GDBusServerModule (); - } else if (context.profile == Profile.DOVA) { - context.codegen = new DovaErrorModule (); } else { context.codegen = new CCodeDelegateModule (); } diff --git a/vala/Makefile.am b/vala/Makefile.am index 999a63a1d..d6df89422 100644 --- a/vala/Makefile.am +++ b/vala/Makefile.am @@ -85,13 +85,11 @@ libvalacore_la_VALASOURCES = \ valainterfacetype.vala \ valainvalidtype.vala \ valalambdaexpression.vala \ - valalistliteral.vala \ valaliteral.vala \ valalocalvariable.vala \ valalockable.vala \ valalockstatement.vala \ valaloop.vala \ - valamapliteral.vala \ valamarkupreader.vala \ valamemberaccess.vala \ valamemberinitializer.vala \ @@ -123,7 +121,6 @@ libvalacore_la_VALASOURCES = \ valascanner.vala \ valascope.vala \ valasemanticanalyzer.vala \ - valasetliteral.vala \ valasignal.vala \ valasignaltype.vala \ valasizeofexpression.vala \ diff --git a/vala/valaarraytype.vala b/vala/valaarraytype.vala index ecd8a0e5c..c190d1d84 100644 --- a/vala/valaarraytype.vala +++ b/vala/valaarraytype.vala @@ -245,8 +245,6 @@ public class Vala.ArrayType : ReferenceType { public override bool is_disposable () { if (fixed_length) { return element_type.is_disposable (); - } else if (CodeContext.get ().profile == Profile.DOVA) { - return false; } else { return base.is_disposable (); } diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala index 1457de335..22c448384 100644 --- a/vala/valabinaryexpression.vala +++ b/vala/valabinaryexpression.vala @@ -263,14 +263,6 @@ public class Vala.BinaryExpression : Expression { && operator == BinaryOperator.PLUS) { // string concatenation - if (context.profile == Profile.DOVA) { - var concat_call = new MethodCall (new MemberAccess (left, "concat", source_reference), source_reference); - concat_call.add_argument (right); - concat_call.target_type = target_type; - parent_node.replace_expression (this, concat_call); - return concat_call.check (context); - } - if (right.value_type == null || right.value_type.data_type != context.analyzer.string_type.data_type) { error = true; Report.error (source_reference, "Operands must be strings"); @@ -283,16 +275,7 @@ public class Vala.BinaryExpression : Expression { } else { value_type.value_owned = true; } - } else if (context.profile == Profile.DOVA && left.value_type.data_type == context.analyzer.list_type.data_type - && operator == BinaryOperator.PLUS) { - // list concatenation - - var concat_call = new MethodCall (new MemberAccess (left, "concat", source_reference), source_reference); - concat_call.add_argument (right); - concat_call.target_type = target_type; - parent_node.replace_expression (this, concat_call); - return concat_call.check (context); - } else if (context.profile != Profile.DOVA && left.value_type is ArrayType && operator == BinaryOperator.PLUS) { + } else if (left.value_type is ArrayType && operator == BinaryOperator.PLUS) { // array concatenation var array_type = (ArrayType) left.value_type; @@ -329,11 +312,7 @@ public class Vala.BinaryExpression : Expression { } } else if (right.value_type is PointerType) { // pointer arithmetic: pointer - pointer - if (context.profile == Profile.DOVA) { - value_type = context.analyzer.long_type; - } else { - value_type = context.analyzer.size_t_type; - } + value_type = context.analyzer.size_t_type; } } else { left.target_type.nullable = false; @@ -427,26 +406,6 @@ public class Vala.BinaryExpression : Expression { } } - if (left.value_type.compatible (context.analyzer.string_type) - && right.value_type.compatible (context.analyzer.string_type)) { - // string comparison - if (context.profile == Profile.DOVA) { - var string_ma = new MemberAccess.simple ("string", source_reference); - string_ma.qualified = true; - var equals_call = new MethodCall (new MemberAccess (string_ma, "equals", source_reference), source_reference); - equals_call.add_argument (left); - equals_call.add_argument (right); - if (operator == BinaryOperator.EQUALITY) { - parent_node.replace_expression (this, equals_call); - return equals_call.check (context); - } else { - var not = new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, equals_call, source_reference); - parent_node.replace_expression (this, not); - return not.check (context); - } - } - } - value_type = context.analyzer.bool_type; } else if (operator == BinaryOperator.BITWISE_AND || operator == BinaryOperator.BITWISE_OR) { diff --git a/vala/valacharacterliteral.vala b/vala/valacharacterliteral.vala index d38a0e6de..71bed95a1 100644 --- a/vala/valacharacterliteral.vala +++ b/vala/valacharacterliteral.vala @@ -90,14 +90,10 @@ public class Vala.CharacterLiteral : Literal { checked = true; - if (context.profile == Profile.DOVA) { - value_type = new IntegerType ((Struct) context.analyzer.root_symbol.scope.lookup ("char"), get_char ().to_string (), "int"); + if (get_char () < 128) { + value_type = new IntegerType ((Struct) context.analyzer.root_symbol.scope.lookup ("char")); } else { - if (get_char () < 128) { - value_type = new IntegerType ((Struct) context.analyzer.root_symbol.scope.lookup ("char")); - } else { - value_type = new IntegerType ((Struct) context.analyzer.root_symbol.scope.lookup ("unichar")); - } + value_type = new IntegerType ((Struct) context.analyzer.root_symbol.scope.lookup ("unichar")); } return !error; diff --git a/vala/valaclass.vala b/vala/valaclass.vala index 87a044187..678c643a9 100644 --- a/vala/valaclass.vala +++ b/vala/valaclass.vala @@ -254,32 +254,6 @@ public class Vala.Class : ObjectTypeSymbol { * @param f a field */ public override void add_field (Field f) { - if (CodeContext.get ().profile == Profile.DOVA && - f.binding == MemberBinding.INSTANCE && - (f.access == SymbolAccessibility.PUBLIC || f.access == SymbolAccessibility.PROTECTED) && - name != "any" /* temporary workaround */) { - // public/protected instance fields not supported, convert to automatic property - - var prop = new Property (f.name, f.variable_type.copy (), null, null, f.source_reference, comment); - prop.access = access; - - var get_type = prop.property_type.copy (); - get_type.value_owned = true; - var set_type = prop.property_type.copy (); - set_type.value_owned = false; - - prop.get_accessor = new PropertyAccessor (true, false, false, get_type, null, f.source_reference); - - prop.set_accessor = new PropertyAccessor (false, true, false, set_type, null, f.source_reference); - - f.name = "_%s".printf (f.name); - f.access = SymbolAccessibility.PRIVATE; - prop.field = f; - - add_property (prop); - return; - } - fields.add (f); if (f.access == SymbolAccessibility.PRIVATE && f.binding == MemberBinding.INSTANCE) { has_private_fields = true; @@ -320,7 +294,7 @@ public class Vala.Class : ObjectTypeSymbol { m.this_parameter = new Parameter ("this", get_this_type ()); m.scope.add (m.this_parameter.name, m.this_parameter); } - if (!(m.return_type is VoidType) && (CodeContext.get ().profile == Profile.DOVA || m.get_postconditions ().size > 0)) { + if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) { if (m.result_var != null) { m.scope.remove (m.result_var.name); } @@ -560,8 +534,6 @@ public class Vala.Class : ObjectTypeSymbol { public bool is_fundamental () { if (!is_compact && base_class == null) { return true; - } else if (CodeContext.get ().profile == Profile.DOVA && base_class.base_class == null) { - return true; } return false; } diff --git a/vala/valacodecontext.vala b/vala/valacodecontext.vala index f2b8b5991..6167b5597 100644 --- a/vala/valacodecontext.vala +++ b/vala/valacodecontext.vala @@ -417,11 +417,6 @@ public class Vala.CodeContext { var ns_ref = new UsingDirective (new UnresolvedSymbol (null, "GLib", null)); source_file.add_using_directive (ns_ref); root.add_using_directive (ns_ref); - } else if (profile == Profile.DOVA) { - // import the Dova namespace by default (namespace of backend-specific standard library) - var ns_ref = new UsingDirective (new UnresolvedSymbol (null, "Dova", null)); - source_file.add_using_directive (ns_ref); - root.add_using_directive (ns_ref); } add_source_file (source_file); diff --git a/vala/valacodevisitor.vala b/vala/valacodevisitor.vala index 395009d89..c9b158694 100644 --- a/vala/valacodevisitor.vala +++ b/vala/valacodevisitor.vala @@ -485,30 +485,6 @@ public abstract class Vala.CodeVisitor { public virtual void visit_template (Template tmpl) { } - /** - * Visit operation called for list literals. - * - * @param lit a list literal - */ - public virtual void visit_list_literal (ListLiteral lit) { - } - - /** - * Visit operation called for set literals. - * - * @param lit a set literal - */ - public virtual void visit_set_literal (SetLiteral lit) { - } - - /** - * Visit operation called for map literals. - * - * @param lit a map literal - */ - public virtual void visit_map_literal (MapLiteral lit) { - } - /** * Visit operation called for tuples. * diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala index 3986e706f..7a7961495 100644 --- a/vala/valacodewriter.vala +++ b/vala/valacodewriter.vala @@ -724,9 +724,7 @@ public class Vala.CodeWriter : CodeVisitor { write_params (m.get_parameters ()); - if (context.profile != Profile.DOVA) { - write_error_domains (m.get_error_types ()); - } + write_error_domains (m.get_error_types ()); write_code_block (m.body); @@ -767,7 +765,7 @@ public class Vala.CodeWriter : CodeVisitor { write_property_accessor_accessibility (prop.get_accessor); - if (context.profile != Profile.DOVA && prop.get_accessor.value_type.is_disposable ()) { + if (prop.get_accessor.value_type.is_disposable ()) { write_string (" owned"); } @@ -779,7 +777,7 @@ public class Vala.CodeWriter : CodeVisitor { write_property_accessor_accessibility (prop.set_accessor); - if (context.profile != Profile.DOVA && prop.set_accessor.value_type.value_owned) { + if (prop.set_accessor.value_type.value_owned) { write_string (" owned"); } @@ -1429,9 +1427,8 @@ public class Vala.CodeWriter : CodeVisitor { private void write_identifier (string s) { char* id = (char*)s; int id_length = (int)s.length; - if (context.profile != Profile.DOVA && - (Vala.Scanner.get_identifier_or_keyword (id, id_length) != Vala.TokenType.IDENTIFIER || - s.get_char ().isdigit ())) { + if (Vala.Scanner.get_identifier_or_keyword (id, id_length) != Vala.TokenType.IDENTIFIER || + s.get_char ().isdigit ()) { stream.putc ('@'); } write_string (s); diff --git a/vala/valadatatype.vala b/vala/valadatatype.vala index c553dcf19..e48d12d2d 100644 --- a/vala/valadatatype.vala +++ b/vala/valadatatype.vala @@ -274,11 +274,6 @@ public abstract class Vala.DataType : CodeNode { } } - if (this is ValueType && target_type.data_type != null && target_type.data_type.get_full_name () == "Dova.Value") { - // allow implicit conversion to Dova.Value - return true; - } - if (target_type is DelegateType && this is DelegateType) { return ((DelegateType) target_type).delegate_symbol == ((DelegateType) this).delegate_symbol; } diff --git a/vala/valaelementaccess.vala b/vala/valaelementaccess.vala index 58f0e4dd3..8210e47e6 100644 --- a/vala/valaelementaccess.vala +++ b/vala/valaelementaccess.vala @@ -115,8 +115,6 @@ public class Vala.ElementAccess : Expression { return false; } - var container_type = container.value_type.data_type; - if (container is MemberAccess && container.symbol_reference is Signal) { // signal detail access if (get_indices ().size != 1) { @@ -163,40 +161,6 @@ public class Vala.ElementAccess : Expression { } } else if (pointer_type != null && !pointer_type.base_type.is_reference_type_or_type_parameter ()) { value_type = pointer_type.base_type.copy (); - } else if (context.profile == Profile.DOVA && container_type == context.analyzer.tuple_type.data_type) { - if (get_indices ().size != 1) { - error = true; - Report.error (source_reference, "Element access with more than one dimension is not supported for tuples"); - return false; - } - var index = get_indices ().get (0) as IntegerLiteral; - if (index == null) { - error = true; - Report.error (source_reference, "Element access with non-literal index is not supported for tuples"); - return false; - } - int i = int.parse (index.value); - if (container.value_type.get_type_arguments ().size == 0) { - error = true; - Report.error (source_reference, "Element access is not supported for untyped tuples"); - return false; - } - if (i < 0 || i >= container.value_type.get_type_arguments ().size) { - error = true; - Report.error (source_reference, "Index out of range"); - return false; - } - - value_type = container.value_type.get_type_arguments ().get (i); - - // replace element access by call to generic get method - var ma = new MemberAccess (container, "get", source_reference); - ma.add_type_argument (value_type); - var get_call = new MethodCall (ma, source_reference); - get_call.add_argument (index); - get_call.target_type = this.target_type; - parent_node.replace_expression (this, get_call); - return get_call.check (context); } else if (container is MemberAccess && container.symbol_reference is Signal) { index_int_type_check = false; diff --git a/vala/valaenum.vala b/vala/valaenum.vala index eeabda917..acb8eb35c 100644 --- a/vala/valaenum.vala +++ b/vala/valaenum.vala @@ -83,7 +83,7 @@ public class Vala.Enum : TypeSymbol { m.this_parameter = new Parameter ("this", new EnumValueType (this)); m.scope.add (m.this_parameter.name, m.this_parameter); } - if (!(m.return_type is VoidType) && (CodeContext.get ().profile == Profile.DOVA || m.get_postconditions ().size > 0)) { + if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) { m.result_var = new LocalVariable (m.return_type.copy (), "result", null, source_reference); m.result_var.is_result = true; } diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala index ada3254d3..57453ee03 100644 --- a/vala/valaflowanalyzer.vala +++ b/vala/valaflowanalyzer.vala @@ -193,12 +193,6 @@ public class Vala.FlowAnalyzer : CodeVisitor { m.return_block.connect (m.exit_block); - if (context.profile == Profile.DOVA && m.result_var != null) { - // ensure result is defined at end of method - var result_ma = new MemberAccess.simple ("result", m.source_reference); - result_ma.symbol_reference = m.result_var; - m.return_block.add_node (result_ma); - } if (m is Method) { // ensure out parameters are defined at end of method foreach (var param in ((Method) m).get_parameters ()) { @@ -224,7 +218,7 @@ public class Vala.FlowAnalyzer : CodeVisitor { if (current_block != null) { // end of method body reachable - if (context.profile != Profile.DOVA && m.has_result) { + if (m.has_result) { Report.error (m.source_reference, "missing return statement at end of subroutine body"); m.error = true; } diff --git a/vala/valaforeachstatement.vala b/vala/valaforeachstatement.vala index 319968af6..f27e30371 100644 --- a/vala/valaforeachstatement.vala +++ b/vala/valaforeachstatement.vala @@ -167,7 +167,7 @@ public class Vala.ForeachStatement : Block { var collection_type = collection.value_type.copy (); collection.target_type = collection_type.copy (); - if (context.profile != Profile.DOVA && collection_type.is_array ()) { + if (collection_type.is_array ()) { var array_type = (ArrayType) collection_type; // can't use inline-allocated array for temporary variable diff --git a/vala/valagenerictype.vala b/vala/valagenerictype.vala index c7d7991c6..49a4c5723 100644 --- a/vala/valagenerictype.vala +++ b/vala/valagenerictype.vala @@ -47,13 +47,6 @@ public class Vala.GenericType : DataType { } public override Symbol? get_member (string member_name) { - if (CodeContext.get ().profile == Profile.DOVA) { - if (member_name == "equals") { - return CodeContext.get ().root.scope.lookup ("Dova").scope.lookup ("Object").scope.lookup ("equals"); - } else if (member_name == "hash") { - return CodeContext.get ().root.scope.lookup ("Dova").scope.lookup ("Object").scope.lookup ("hash"); - } - } return null; } } diff --git a/vala/valaintegerliteral.vala b/vala/valaintegerliteral.vala index e16c4577e..879bd2a7c 100644 --- a/vala/valaintegerliteral.vala +++ b/vala/valaintegerliteral.vala @@ -96,14 +96,6 @@ public class Vala.IntegerLiteral : Literal { type_suffix = ""; type_name = "int"; } - } else if (CodeContext.get ().profile == Profile.DOVA) { - if (u) { - type_suffix = "UL"; - type_name = "uint64"; - } else { - type_suffix = "L"; - type_name = "int64"; - } } else if (l == 1) { if (u) { type_suffix = "UL"; @@ -123,7 +115,7 @@ public class Vala.IntegerLiteral : Literal { } var st = (Struct) context.analyzer.root_symbol.scope.lookup (type_name); - // ensure attributes are already processed in case of bootstrapping dova-core + // ensure attributes are already processed st.check (context); value_type = new IntegerType (st, value, type_name); diff --git a/vala/valainterface.vala b/vala/valainterface.vala index 548304f07..5780837ff 100644 --- a/vala/valainterface.vala +++ b/vala/valainterface.vala @@ -133,7 +133,7 @@ public class Vala.Interface : ObjectTypeSymbol { m.this_parameter = new Parameter ("this", get_this_type ()); m.scope.add (m.this_parameter.name, m.this_parameter); } - if (!(m.return_type is VoidType) && (CodeContext.get ().profile == Profile.DOVA || m.get_postconditions ().size > 0)) { + if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) { m.result_var = new LocalVariable (m.return_type.copy (), "result", null, source_reference); m.result_var.is_result = true; } diff --git a/vala/valalambdaexpression.vala b/vala/valalambdaexpression.vala index 027beaf05..61482f42a 100644 --- a/vala/valalambdaexpression.vala +++ b/vala/valalambdaexpression.vala @@ -164,11 +164,6 @@ public class Vala.LambdaExpression : Expression { } method.owner = context.analyzer.current_symbol.scope; - if (!(method.return_type is VoidType) && CodeContext.get ().profile == Profile.DOVA) { - method.result_var = new LocalVariable (method.return_type.copy (), "result", null, source_reference); - method.result_var.is_result = true; - } - var lambda_params = get_parameters (); Iterator lambda_param_it = lambda_params.iterator (); @@ -208,12 +203,7 @@ public class Vala.LambdaExpression : Expression { block.scope.parent_scope = method.scope; if (method.return_type.data_type != null) { - if (context.profile == Profile.DOVA) { - block.add_statement (new ExpressionStatement (new Assignment (new MemberAccess.simple ("result", source_reference), expression_body, AssignmentOperator.SIMPLE, source_reference), source_reference)); - block.add_statement (new ReturnStatement (null, source_reference)); - } else { - block.add_statement (new ReturnStatement (expression_body, source_reference)); - } + block.add_statement (new ReturnStatement (expression_body, source_reference)); } else { block.add_statement (new ExpressionStatement (expression_body, source_reference)); } diff --git a/vala/valalistliteral.vala b/vala/valalistliteral.vala deleted file mode 100644 index 7438ca7d5..000000000 --- a/vala/valalistliteral.vala +++ /dev/null @@ -1,140 +0,0 @@ -/* valalistliteral.vala - * - * Copyright (C) 2009-2010 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.1 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 - */ - -public class Vala.ListLiteral : Literal { - private List expression_list = new ArrayList (); - - public DataType element_type { get; private set; } - - public ListLiteral (SourceReference? source_reference = null) { - this.source_reference = source_reference; - } - - public override void accept_children (CodeVisitor visitor) { - foreach (Expression expr in expression_list) { - expr.accept (visitor); - } - } - - public override void accept (CodeVisitor visitor) { - visitor.visit_list_literal (this); - - visitor.visit_expression (this); - } - - public void add_expression (Expression expr) { - expression_list.add (expr); - expr.parent_node = this; - } - - public List get_expressions () { - return expression_list; - } - - public override bool is_pure () { - return false; - } - - public override void replace_expression (Expression old_node, Expression new_node) { - for (int i = 0; i < expression_list.size; i++) { - if (expression_list[i] == old_node) { - expression_list[i] = new_node; - } - } - } - - public override bool check (CodeContext context) { - if (checked) { - return !error; - } - - checked = true; - - // list literals are also allowed for constant arrays, - // however, they are currently handled by InitializerList - // therefore transform this expression if necessary - var array_type = target_type as ArrayType; - if (array_type != null && array_type.inline_allocated) { - var initializer = new InitializerList (source_reference); - initializer.target_type = target_type; - foreach (var expr in expression_list) { - initializer.append (expr); - } - - context.analyzer.replaced_nodes.add (this); - parent_node.replace_expression (this, initializer); - return initializer.check (context); - } - - var list_type = new ObjectType ((Class) context.root.scope.lookup ("Dova").scope.lookup ("List")); - list_type.value_owned = true; - - bool fixed_element_type = false; - if (target_type != null && target_type.data_type == list_type.data_type && target_type.get_type_arguments ().size == 1) { - element_type = target_type.get_type_arguments ().get (0).copy (); - element_type.value_owned = false; - fixed_element_type = true; - } - - for (int i = 0; i < expression_list.size; i++) { - var expr = expression_list[i]; - - if (fixed_element_type) { - expr.target_type = element_type; - } - if (!expr.check (context)) { - return false; - } - - // expression might have been replaced in the list - expr = expression_list[i]; - - if (element_type == null) { - element_type = expr.value_type.copy (); - element_type.value_owned = false; - } - } - - if (element_type == null) { - error = true; - Report.error (source_reference, "cannot infer element type for list literal"); - return false; - } - - element_type = element_type.copy (); - element_type.value_owned = true; - list_type.add_type_argument (element_type); - value_type = list_type; - - return !error; - } - - public override void emit (CodeGenerator codegen) { - foreach (Expression expr in expression_list) { - expr.emit (codegen); - } - - codegen.visit_list_literal (this); - - codegen.visit_expression (this); - } -} diff --git a/vala/valamapliteral.vala b/vala/valamapliteral.vala deleted file mode 100644 index e9eca0b5d..000000000 --- a/vala/valamapliteral.vala +++ /dev/null @@ -1,151 +0,0 @@ -/* valamapliteral.vala - * - * Copyright (C) 2009-2010 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.1 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 - */ - -public class Vala.MapLiteral : Literal { - private List keys = new ArrayList (); - private List values = new ArrayList (); - - public DataType map_key_type { get; private set; } - public DataType map_value_type { get; private set; } - - public MapLiteral (SourceReference? source_reference = null) { - this.source_reference = source_reference; - } - - public override void accept_children (CodeVisitor visitor) { - for (int i = 0; i < keys.size; i++) { - keys[i].accept (visitor); - values[i].accept (visitor); - } - } - - public override void accept (CodeVisitor visitor) { - visitor.visit_map_literal (this); - - visitor.visit_expression (this); - } - - public void add_key (Expression expr) { - keys.add (expr); - expr.parent_node = this; - } - - public void add_value (Expression expr) { - values.add (expr); - expr.parent_node = this; - } - - public List get_keys () { - return keys; - } - - public List get_values () { - return values; - } - - public override bool is_pure () { - return false; - } - - public override void replace_expression (Expression old_node, Expression new_node) { - for (int i = 0; i < keys.size; i++) { - if (keys[i] == old_node) { - keys[i] = new_node; - } - if (values[i] == old_node) { - values[i] = new_node; - } - } - } - - public override bool check (CodeContext context) { - if (checked) { - return !error; - } - - checked = true; - - var map_type = new ObjectType ((Class) context.root.scope.lookup ("Dova").scope.lookup ("Map")); - map_type.value_owned = true; - - bool fixed_element_type = false; - if (target_type != null && target_type.data_type == map_type.data_type && target_type.get_type_arguments ().size == 2) { - map_key_type = target_type.get_type_arguments ().get (0).copy (); - map_key_type.value_owned = false; - map_value_type = target_type.get_type_arguments ().get (1).copy (); - map_value_type.value_owned = false; - fixed_element_type = true; - } - - for (int i = 0; i < keys.size; i++) { - if (fixed_element_type) { - keys[i].target_type = map_key_type; - values[i].target_type = map_value_type; - } - if (!keys[i].check (context)) { - return false; - } - if (!values[i].check (context)) { - return false; - } - if (map_key_type == null) { - map_key_type = keys[i].value_type.copy (); - map_key_type.value_owned = false; - map_value_type = values[i].value_type.copy (); - map_value_type.value_owned = false; - } - } - - if (map_key_type == null) { - error = true; - Report.error (source_reference, "cannot infer key type for map literal"); - return false; - } - - if (map_value_type == null) { - error = true; - Report.error (source_reference, "cannot infer value type for map literal"); - return false; - } - - map_key_type = map_key_type.copy (); - map_key_type.value_owned = true; - map_value_type = map_value_type.copy (); - map_value_type.value_owned = true; - map_type.add_type_argument (map_key_type); - map_type.add_type_argument (map_value_type); - value_type = map_type; - - return !error; - } - - public override void emit (CodeGenerator codegen) { - for (int i = 0; i < keys.size; i++) { - keys[i].emit (codegen); - values[i].emit (codegen); - } - - codegen.visit_map_literal (this); - - codegen.visit_expression (this); - } -} diff --git a/vala/valamethod.vala b/vala/valamethod.vala index 2a1bf81a2..942f0d2fd 100644 --- a/vala/valamethod.vala +++ b/vala/valamethod.vala @@ -769,7 +769,7 @@ public class Vala.Method : Subroutine { entry_point = true; context.entry_point = this; - if (tree_can_fail && context.profile != Profile.DOVA) { + if (tree_can_fail) { Report.error (source_reference, "\"main\" method cannot throw errors"); } } diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala index 0c6705e4c..0cb8cac04 100644 --- a/vala/valamethodcall.vala +++ b/vala/valamethodcall.vala @@ -724,10 +724,8 @@ public class Vala.MethodCall : Expression { if (parent_node is LocalVariable || parent_node is ExpressionStatement) { // simple statements, no side effects after method call } else if (!(context.analyzer.current_symbol is Block)) { - if (context.profile != Profile.DOVA) { - // can't handle errors in field initializers - Report.error (source_reference, "Field initializers must not throw errors"); - } + // can't handle errors in field initializers + Report.error (source_reference, "Field initializers must not throw errors"); } else { // store parent_node as we need to replace the expression in the old parent node later on var old_parent_node = parent_node; diff --git a/vala/valanamespace.vala b/vala/valanamespace.vala index b605ac646..47dd4eee1 100644 --- a/vala/valanamespace.vala +++ b/vala/valanamespace.vala @@ -438,7 +438,7 @@ public class Vala.Namespace : Symbol { m.error = true; return; } - if (!(m.return_type is VoidType) && (CodeContext.get ().profile == Profile.DOVA || m.get_postconditions ().size > 0)) { + if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) { m.result_var = new LocalVariable (m.return_type.copy (), "result", null, source_reference); m.result_var.is_result = true; } diff --git a/vala/valaobjectcreationexpression.vala b/vala/valaobjectcreationexpression.vala index 400bc4c32..7384746d0 100644 --- a/vala/valaobjectcreationexpression.vala +++ b/vala/valaobjectcreationexpression.vala @@ -407,10 +407,8 @@ public class Vala.ObjectCreationExpression : Expression { if (parent_node is LocalVariable || parent_node is ExpressionStatement) { // simple statements, no side effects after method call } else if (!(context.analyzer.current_symbol is Block)) { - if (context.profile != Profile.DOVA) { - // can't handle errors in field initializers - Report.error (source_reference, "Field initializers must not throw errors"); - } + // can't handle errors in field initializers + Report.error (source_reference, "Field initializers must not throw errors"); } else { // store parent_node as we need to replace the expression in the old parent node later on var old_parent_node = parent_node; diff --git a/vala/valaobjecttype.vala b/vala/valaobjecttype.vala index 6d440b181..7019719b3 100644 --- a/vala/valaobjecttype.vala +++ b/vala/valaobjecttype.vala @@ -100,11 +100,6 @@ public class Vala.ObjectType : ReferenceType { return false; } - if (context.profile == Profile.DOVA && type_symbol.get_full_name () == "Dova.Tuple") { - // tuples have variadic generics - return true; - } - int n_type_args = get_type_arguments ().size; if (n_type_args > 0 && n_type_args < type_symbol.get_type_parameters ().size) { Report.error (source_reference, "too few type arguments"); diff --git a/vala/valaparser.vala b/vala/valaparser.vala index d01558b21..0f7d0e378 100644 --- a/vala/valaparser.vala +++ b/vala/valaparser.vala @@ -409,11 +409,7 @@ public class Vala.Parser : CodeVisitor { bool value_owned = owned_by_default; if (owned_by_default) { - if (context.profile == Profile.DOVA) { - if (can_weak_ref && accept (TokenType.WEAK)) { - value_owned = false; - } - } else if (accept (TokenType.UNOWNED)) { + if (accept (TokenType.UNOWNED)) { value_owned = false; } else if (accept (TokenType.WEAK)) { if (!can_weak_ref && !context.deprecated) { @@ -422,7 +418,7 @@ public class Vala.Parser : CodeVisitor { value_owned = false; } } else { - value_owned = (context.profile != Profile.DOVA && accept (TokenType.OWNED)); + value_owned = accept (TokenType.OWNED); } DataType type; @@ -463,7 +459,7 @@ public class Vala.Parser : CodeVisitor { // only used for parsing, reject use as real type invalid_array = true; } - } while (context.profile != Profile.DOVA && accept (TokenType.COMMA)); + } while (accept (TokenType.COMMA)); expect (TokenType.CLOSE_BRACKET); // arrays contain strong references by default @@ -481,7 +477,7 @@ public class Vala.Parser : CodeVisitor { } if (!owned_by_default) { - if (context.profile != Profile.DOVA && accept (TokenType.HASH)) { + if (accept (TokenType.HASH)) { if (!context.deprecated) { Report.warning (get_last_src (), "deprecated syntax, use `owned` modifier"); } @@ -579,18 +575,10 @@ public class Vala.Parser : CodeVisitor { expr = parse_literal (); break; case TokenType.OPEN_BRACE: - if (context.profile == Profile.DOVA) { - expr = parse_set_literal (); - } else { - expr = parse_initializer (); - } + expr = parse_initializer (); break; case TokenType.OPEN_BRACKET: - if (context.profile == Profile.DOVA) { - expr = parse_list_literal (); - } else { - expr = parse_simple_name (); - } + expr = parse_simple_name (); break; case TokenType.OPEN_PARENS: expr = parse_tuple (); @@ -632,11 +620,7 @@ public class Vala.Parser : CodeVisitor { expr = parse_member_access (begin, expr); break; case TokenType.OP_PTR: - if (context.profile == Profile.DOVA) { - found = false; - } else { - expr = parse_pointer_member_access (begin, expr); - } + expr = parse_pointer_member_access (begin, expr); break; case TokenType.OPEN_PARENS: expr = parse_method_call (begin, expr); @@ -644,14 +628,6 @@ public class Vala.Parser : CodeVisitor { case TokenType.OPEN_BRACKET: expr = parse_element_access (begin, expr); break; - case TokenType.OPEN_BRACE: - var ma = expr as MemberAccess; - if (context.profile == Profile.DOVA && ma != null) { - expr = parse_object_literal (begin, ma); - } else { - found = false; - } - break; case TokenType.OP_INC: expr = parse_post_increment_expression (begin, expr); break; @@ -877,27 +853,6 @@ public class Vala.Parser : CodeVisitor { return expr; } - Expression parse_object_literal (SourceLocation begin, MemberAccess member) throws ParseError { - member.creation_member = true; - - var expr = new ObjectCreationExpression (member, get_src (begin)); - - expect (TokenType.OPEN_BRACE); - - do { - var member_begin = get_location (); - string id = parse_identifier (); - expect (TokenType.COLON); - var member_expr = parse_expression (); - - expr.add_member_initializer (new MemberInitializer (id, member_expr, get_src (member_begin))); - } while (accept (TokenType.COMMA)); - - expect (TokenType.CLOSE_BRACE); - - return expr; - } - Expression parse_array_creation_expression () throws ParseError { var begin = get_location (); expect (TokenType.NEW); @@ -939,12 +894,12 @@ public class Vala.Parser : CodeVisitor { size_specified = true; } size_specifier_list.add (size); - } while (context.profile != Profile.DOVA && accept (TokenType.COMMA)); + } while (accept (TokenType.COMMA)); expect (TokenType.CLOSE_BRACKET); } while (accept (TokenType.OPEN_BRACKET)); InitializerList initializer = null; - if (context.profile != Profile.DOVA && current () == TokenType.OPEN_BRACE) { + if (current () == TokenType.OPEN_BRACE) { initializer = parse_initializer (); } var expr = new ArrayCreationExpression (element_type, size_specifier_list.size, initializer, get_src (begin)); @@ -958,7 +913,7 @@ public class Vala.Parser : CodeVisitor { List parse_object_initializer () throws ParseError { var list = new ArrayList (); - if (context.profile != Profile.DOVA && accept (TokenType.OPEN_BRACE)) { + if (accept (TokenType.OPEN_BRACE)) { do { list.add (parse_member_initializer ()); } while (accept (TokenType.COMMA)); @@ -1568,19 +1523,6 @@ public class Vala.Parser : CodeVisitor { } if (!is_decl) { - if (context.profile == Profile.DOVA && stmt is ReturnStatement) { - // split - // return foo; - // into - // result = foo; - // return; - var ret_stmt = (ReturnStatement) stmt; - if (ret_stmt.return_expression != null) { - var assignment = new Assignment (new MemberAccess.simple ("result", stmt.source_reference), ret_stmt.return_expression, AssignmentOperator.SIMPLE, stmt.source_reference); - ret_stmt.return_expression = null; - block.add_statement (new ExpressionStatement (assignment, stmt.source_reference)); - } - } block.add_statement (stmt); } } catch (ParseError e) { @@ -1683,19 +1625,6 @@ public class Vala.Parser : CodeVisitor { var block = new Block (get_src (get_location ())); var stmt = parse_embedded_statement_without_block (); - if (context.profile == Profile.DOVA && stmt is ReturnStatement) { - // split - // return foo; - // into - // result = foo; - // return; - var ret_stmt = (ReturnStatement) stmt; - if (ret_stmt.return_expression != null) { - var assignment = new Assignment (new MemberAccess.simple ("result"), ret_stmt.return_expression); - ret_stmt.return_expression = null; - block.add_statement (new ExpressionStatement (assignment)); - } - } block.add_statement (stmt); return block; @@ -2187,7 +2116,7 @@ public class Vala.Parser : CodeVisitor { method.body.source_reference.end = get_current_src ().end; - if (!context.experimental && context.profile != Profile.DOVA) { + if (!context.experimental) { Report.warning (method.source_reference, "main blocks are experimental"); } @@ -2576,9 +2505,6 @@ public class Vala.Parser : CodeVisitor { var begin = get_location (); var access = parse_access_modifier (); var flags = parse_member_declaration_modifiers (); - if (context.profile == Profile.DOVA) { - accept (TokenType.VOLATILE); - } var type = parse_type (true, true); string id = parse_identifier (); @@ -2627,58 +2553,6 @@ public class Vala.Parser : CodeVisitor { return initializer; } - ListLiteral parse_list_literal () throws ParseError { - var begin = get_location (); - expect (TokenType.OPEN_BRACKET); - var initializer = new ListLiteral (get_src (begin)); - if (current () != TokenType.CLOSE_BRACKET) { - do { - var init = parse_expression (); - initializer.add_expression (init); - } while (accept (TokenType.COMMA)); - } - expect (TokenType.CLOSE_BRACKET); - return initializer; - } - - Expression parse_set_literal () throws ParseError { - var begin = get_location (); - expect (TokenType.OPEN_BRACE); - var set = new SetLiteral (get_src (begin)); - bool first = true; - if (current () != TokenType.CLOSE_BRACE) { - do { - var expr = parse_expression (); - if (first && accept (TokenType.COLON)) { - // found colon after expression, it's a map - rollback (begin); - return parse_map_literal (); - } - first = false; - set.add_expression (expr); - } while (accept (TokenType.COMMA)); - } - expect (TokenType.CLOSE_BRACE); - return set; - } - - Expression parse_map_literal () throws ParseError { - var begin = get_location (); - expect (TokenType.OPEN_BRACE); - var map = new MapLiteral (get_src (begin)); - if (current () != TokenType.CLOSE_BRACE) { - do { - var key = parse_expression (); - map.add_key (key); - expect (TokenType.COLON); - var value = parse_expression (); - map.add_value (value); - } while (accept (TokenType.COMMA)); - } - expect (TokenType.CLOSE_BRACE); - return map; - } - void parse_method_declaration (Symbol parent, List? attrs) throws ParseError { var begin = get_location (); var access = parse_access_modifier (); @@ -2741,21 +2615,10 @@ public class Vala.Parser : CodeVisitor { } while (accept (TokenType.COMMA)); } expect (TokenType.CLOSE_PARENS); - if (context.profile == Profile.DOVA) { - var error_type = new UnresolvedType.from_symbol (new UnresolvedSymbol (new UnresolvedSymbol (null, "Dova"), "Error"), method.source_reference); - method.add_error_type (error_type); - if (accept (TokenType.THROWS)) { - do { - parse_type (true, false); - } while (accept (TokenType.COMMA)); - Report.warning (method.source_reference, "`throws' is ignored in the Dova profile"); - } - } else { - if (accept (TokenType.THROWS)) { - do { - method.add_error_type (parse_type (true, false)); - } while (accept (TokenType.COMMA)); - } + if (accept (TokenType.THROWS)) { + do { + method.add_error_type (parse_type (true, false)); + } while (accept (TokenType.COMMA)); } while (accept (TokenType.REQUIRES)) { expect (TokenType.OPEN_PARENS); @@ -2783,9 +2646,7 @@ public class Vala.Parser : CodeVisitor { var type = parse_type (true, true); bool getter_owned = false; - if (context.profile == Profile.DOVA) { - getter_owned = true; - } else if (accept (TokenType.HASH)) { + if (accept (TokenType.HASH)) { if (!context.deprecated) { Report.warning (get_last_src (), "deprecated syntax, use `owned` modifier before `get'"); } @@ -2819,14 +2680,11 @@ public class Vala.Parser : CodeVisitor { if (ModifierFlags.EXTERN in flags || scanner.source_file.file_type == SourceFileType.PACKAGE) { prop.external = true; } - if (context.profile == Profile.DOVA) { - } else { - if (accept (TokenType.THROWS)) { - do { - prop.add_error_type (parse_type (true, false)); - } while (accept (TokenType.COMMA)); - Report.error (prop.source_reference, "properties throwing errors are not supported yet"); - } + if (accept (TokenType.THROWS)) { + do { + prop.add_error_type (parse_type (true, false)); + } while (accept (TokenType.COMMA)); + Report.error (prop.source_reference, "properties throwing errors are not supported yet"); } expect (TokenType.OPEN_BRACE); while (current () != TokenType.CLOSE_BRACE) { @@ -2845,7 +2703,7 @@ public class Vala.Parser : CodeVisitor { var accessor_access = parse_access_modifier (SymbolAccessibility.PUBLIC); var value_type = type.copy (); - value_type.value_owned = (context.profile != Profile.DOVA && accept (TokenType.OWNED)); + value_type.value_owned = accept (TokenType.OWNED); if (accept (TokenType.GET)) { if (prop.get_accessor != null) { @@ -3292,9 +3150,6 @@ public class Vala.Parser : CodeVisitor { direction = ParameterDirection.REF; } - if (context.profile == Profile.DOVA) { - accept (TokenType.VOLATILE); - } DataType type; if (direction == ParameterDirection.IN) { // in parameters are unowned by default @@ -3353,21 +3208,10 @@ public class Vala.Parser : CodeVisitor { } while (accept (TokenType.COMMA)); } expect (TokenType.CLOSE_PARENS); - if (context.profile == Profile.DOVA) { - var error_type = new UnresolvedType.from_symbol (new UnresolvedSymbol (new UnresolvedSymbol (null, "Dova"), "Error"), method.source_reference); - method.add_error_type (error_type); - if (accept (TokenType.THROWS)) { - do { - parse_type (true, false); - } while (accept (TokenType.COMMA)); - Report.warning (method.source_reference, "`throws' is ignored in the Dova profile"); - } - } else { - if (accept (TokenType.THROWS)) { - do { - method.add_error_type (parse_type (true, false)); - } while (accept (TokenType.COMMA)); - } + if (accept (TokenType.THROWS)) { + do { + method.add_error_type (parse_type (true, false)); + } while (accept (TokenType.COMMA)); } while (accept (TokenType.REQUIRES)) { expect (TokenType.OPEN_PARENS); @@ -3425,21 +3269,10 @@ public class Vala.Parser : CodeVisitor { } while (accept (TokenType.COMMA)); } expect (TokenType.CLOSE_PARENS); - if (context.profile == Profile.DOVA) { - var error_type = new UnresolvedType.from_symbol (new UnresolvedSymbol (new UnresolvedSymbol (null, "Dova"), "Error"), d.source_reference); - d.add_error_type (error_type); - if (accept (TokenType.THROWS)) { - do { - parse_type (true, false); - } while (accept (TokenType.COMMA)); - Report.warning (d.source_reference, "`throws' is ignored in the Dova profile"); - } - } else { - if (accept (TokenType.THROWS)) { - do { - d.add_error_type (parse_type (true, false)); - } while (accept (TokenType.COMMA)); - } + if (accept (TokenType.THROWS)) { + do { + d.add_error_type (parse_type (true, false)); + } while (accept (TokenType.COMMA)); } expect (TokenType.SEMICOLON); diff --git a/vala/valapointertype.vala b/vala/valapointertype.vala index fce8e9b6b..d0f938dc4 100644 --- a/vala/valapointertype.vala +++ b/vala/valapointertype.vala @@ -92,17 +92,7 @@ public class Vala.PointerType : DataType { } public override Symbol? get_member (string member_name) { - if (CodeContext.get ().profile != Profile.DOVA) { - return null; - } - - Symbol base_symbol = base_type.data_type; - - if (base_symbol == null) { - return null; - } - - return SemanticAnalyzer.symbol_lookup_inherited (base_symbol, member_name); + return null; } public override Symbol? get_pointer_member (string member_name) { diff --git a/vala/valaprofile.vala b/vala/valaprofile.vala index 52108266e..677930fbb 100644 --- a/vala/valaprofile.vala +++ b/vala/valaprofile.vala @@ -22,6 +22,5 @@ public enum Vala.Profile { POSIX, - GOBJECT, - DOVA + GOBJECT } diff --git a/vala/valapropertyaccessor.vala b/vala/valapropertyaccessor.vala index 47a197772..466fe6c18 100644 --- a/vala/valapropertyaccessor.vala +++ b/vala/valapropertyaccessor.vala @@ -143,12 +143,7 @@ public class Vala.PropertyAccessor : Subroutine { body = new Block (source_reference); var ma = new MemberAccess.simple ("_%s".printf (prop.name), source_reference); if (readable) { - if (context.profile == Profile.DOVA) { - body.add_statement (new ExpressionStatement (new Assignment (new MemberAccess.simple ("result", source_reference), ma, AssignmentOperator.SIMPLE, source_reference), source_reference)); - body.add_statement (new ReturnStatement (null, source_reference)); - } else { - body.add_statement (new ReturnStatement (ma, source_reference)); - } + body.add_statement (new ReturnStatement (ma, source_reference)); } else { Expression value = new MemberAccess.simple ("value", source_reference); if (value_type.value_owned) { @@ -161,23 +156,16 @@ public class Vala.PropertyAccessor : Subroutine { } if (body != null) { - if (readable && context.profile == Profile.DOVA) { - result_var = new LocalVariable (value_type.copy (), "result", null, source_reference); - result_var.is_result = true; - - result_var.check (context); - } else if (writable || construction) { + if (writable || construction) { value_parameter = new Parameter ("value", value_type, source_reference); body.scope.add (value_parameter.name, value_parameter); } body.check (context); - if (context.profile != Profile.DOVA) { - foreach (DataType body_error_type in body.get_error_types ()) { - if (!((ErrorType) body_error_type).dynamic_error) { - Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string())); - } + foreach (DataType body_error_type in body.get_error_types ()) { + if (!((ErrorType) body_error_type).dynamic_error) { + Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string())); } } } diff --git a/vala/valarealliteral.vala b/vala/valarealliteral.vala index 0acfb8893..0dc01add8 100644 --- a/vala/valarealliteral.vala +++ b/vala/valarealliteral.vala @@ -78,7 +78,7 @@ public class Vala.RealLiteral : Literal { checked = true; var st = (Struct) context.analyzer.root_symbol.scope.lookup (get_type_name ()); - // ensure attributes are already processed in case of bootstrapping dova-core + // ensure attributes are already processed st.check (context); value_type = new FloatingType (st); diff --git a/vala/valareturnstatement.vala b/vala/valareturnstatement.vala index 6a5370580..e407aec4a 100644 --- a/vala/valareturnstatement.vala +++ b/vala/valareturnstatement.vala @@ -93,11 +93,6 @@ public class Vala.ReturnStatement : CodeNode, Statement { return false; } - if (context.profile == Profile.DOVA) { - // no return expressions in Dova profile - return !error; - } - if (return_expression == null) { if (!(context.analyzer.current_return_type is VoidType)) { error = true; diff --git a/vala/valascanner.vala b/vala/valascanner.vala index 926a5374e..ba4736966 100644 --- a/vala/valascanner.vala +++ b/vala/valascanner.vala @@ -774,7 +774,7 @@ public class Vala.Scanner { len++; } type = get_identifier_or_keyword (begin, len); - } else if (current[0] == '@' && source_file.context.profile != Profile.DOVA) { + } else if (current[0] == '@') { if (current < end - 1 && current[1] == '"') { type = TokenType.OPEN_TEMPLATE; current += 2; @@ -1129,13 +1129,6 @@ public class Vala.Scanner { column = 1; token_length_in_chars = 1; } else { - if (type == TokenType.STRING_LITERAL && source_file.context.profile == Profile.DOVA && current[0] == '$') { - // string template - type = TokenType.OPEN_TEMPLATE; - current = begin; - state_stack += State.TEMPLATE; - break; - } unichar u = ((string) current).get_char_validated ((long) (end - current)); if (u != (unichar) (-1)) { current += u.to_utf8 (null); diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 5e8c4f561..3d66b56f3 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -186,22 +186,15 @@ public class Vala.SemanticAnalyzer : CodeVisitor { int_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int")); uint_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint")); - if (context.profile != Profile.DOVA) { - uchar_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uchar")); - int8_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int8")); - short_type = new IntegerType ((Struct) root_symbol.scope.lookup ("short")); - ushort_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ushort")); - long_type = new IntegerType ((Struct) root_symbol.scope.lookup ("long")); - ulong_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ulong")); - size_t_type = new IntegerType ((Struct) root_symbol.scope.lookup ("size_t")); - ssize_t_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ssize_t")); - double_type = new FloatingType ((Struct) root_symbol.scope.lookup ("double")); - } else { - long_type = int_type; - ulong_type = uint_type; - size_t_type = uint_type; - ssize_t_type = int_type; - } + uchar_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uchar")); + int8_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int8")); + short_type = new IntegerType ((Struct) root_symbol.scope.lookup ("short")); + ushort_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ushort")); + long_type = new IntegerType ((Struct) root_symbol.scope.lookup ("long")); + ulong_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ulong")); + size_t_type = new IntegerType ((Struct) root_symbol.scope.lookup ("size_t")); + ssize_t_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ssize_t")); + double_type = new FloatingType ((Struct) root_symbol.scope.lookup ("double")); var unichar_struct = (Struct) root_symbol.scope.lookup ("unichar"); if (unichar_struct != null) { @@ -223,14 +216,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor { gerror_type = (Class) glib_ns.scope.lookup ("Error"); regex_type = new ObjectType ((Class) root_symbol.scope.lookup ("GLib").scope.lookup ("Regex")); - } else if (context.profile == Profile.DOVA) { - var dova_ns = root_symbol.scope.lookup ("Dova"); - - object_type = (Class) dova_ns.scope.lookup ("Object"); - type_type = new ObjectType ((Class) dova_ns.scope.lookup ("Type")); - list_type = new ObjectType ((Class) dova_ns.scope.lookup ("List")); - tuple_type = new ObjectType ((Class) dova_ns.scope.lookup ("Tuple")); - error_type = new ObjectType ((Class) dova_ns.scope.lookup ("Error")); } current_symbol = root_symbol; @@ -631,14 +616,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor { instance_type = instance_pointer_type.base_type; } - if (CodeContext.get ().profile == Profile.DOVA) { - while (instance_type is ArrayType) { - var instance_array_type = (ArrayType) instance_type; - instance_type = new ObjectType ((Class) CodeContext.get ().root.scope.lookup ("Dova").scope.lookup ("Array")); - instance_type.add_type_argument (instance_array_type.element_type); - } - } - if (instance_type is DelegateType && ((DelegateType) instance_type).delegate_symbol == type_symbol) { return instance_type; } else if (instance_type.data_type == type_symbol) { diff --git a/vala/valasetliteral.vala b/vala/valasetliteral.vala deleted file mode 100644 index bf10e0155..000000000 --- a/vala/valasetliteral.vala +++ /dev/null @@ -1,124 +0,0 @@ -/* valasetliteral.vala - * - * Copyright (C) 2009-2010 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.1 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 - */ - -public class Vala.SetLiteral : Literal { - private List expression_list = new ArrayList (); - - public DataType element_type { get; private set; } - - public SetLiteral (SourceReference? source_reference = null) { - this.source_reference = source_reference; - } - - public override void accept_children (CodeVisitor visitor) { - foreach (Expression expr in expression_list) { - expr.accept (visitor); - } - } - - public override void accept (CodeVisitor visitor) { - visitor.visit_set_literal (this); - - visitor.visit_expression (this); - } - - public void add_expression (Expression expr) { - expression_list.add (expr); - expr.parent_node = this; - } - - public List get_expressions () { - return expression_list; - } - - public override bool is_pure () { - return false; - } - - public override void replace_expression (Expression old_node, Expression new_node) { - for (int i = 0; i < expression_list.size; i++) { - if (expression_list[i] == old_node) { - expression_list[i] = new_node; - } - } - } - - public override bool check (CodeContext context) { - if (checked) { - return !error; - } - - checked = true; - - var set_type = new ObjectType ((Class) context.root.scope.lookup ("Dova").scope.lookup ("Set")); - set_type.value_owned = true; - - bool fixed_element_type = false; - if (target_type != null && target_type.data_type == set_type.data_type && target_type.get_type_arguments ().size == 1) { - element_type = target_type.get_type_arguments ().get (0).copy (); - element_type.value_owned = false; - fixed_element_type = true; - } - - for (int i = 0; i < expression_list.size; i++) { - var expr = expression_list[i]; - - if (fixed_element_type) { - expr.target_type = element_type; - } - if (!expr.check (context)) { - return false; - } - - // expression might have been replaced in the list - expr = expression_list[i]; - - if (element_type == null) { - element_type = expr.value_type.copy (); - element_type.value_owned = false; - } - } - - if (element_type == null) { - error = true; - Report.error (source_reference, "cannot infer element type for set literal"); - return false; - } - - element_type = element_type.copy (); - element_type.value_owned = true; - set_type.add_type_argument (element_type); - value_type = set_type; - - return !error; - } - - public override void emit (CodeGenerator codegen) { - foreach (Expression expr in expression_list) { - expr.emit (codegen); - } - - codegen.visit_set_literal (this); - - codegen.visit_expression (this); - } -} diff --git a/vala/valastruct.vala b/vala/valastruct.vala index f913a019c..b9229e099 100644 --- a/vala/valastruct.vala +++ b/vala/valastruct.vala @@ -207,7 +207,7 @@ public class Vala.Struct : TypeSymbol { m.this_parameter = new Parameter ("this", SemanticAnalyzer.get_data_type_for_symbol (this)); m.scope.add (m.this_parameter.name, m.this_parameter); } - if (!(m.return_type is VoidType) && (CodeContext.get ().profile == Profile.DOVA || m.get_postconditions ().size > 0)) { + if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) { m.result_var = new LocalVariable (m.return_type.copy (), "result", null, source_reference); m.result_var.is_result = true; } @@ -407,9 +407,6 @@ public class Vala.Struct : TypeSymbol { * instances are passed by value. */ public bool is_simple_type () { - if (CodeContext.get ().profile == Profile.DOVA) { - return true; - } var st = base_struct; if (st != null && st.is_simple_type ()) { return true; diff --git a/vala/valasymbolresolver.vala b/vala/valasymbolresolver.vala index f11d74ee6..a269df453 100644 --- a/vala/valasymbolresolver.vala +++ b/vala/valasymbolresolver.vala @@ -75,18 +75,6 @@ public class Vala.SymbolResolver : CodeVisitor { } } - if (context.profile == Profile.DOVA) { - // classes derive from Object by default - if (cl.base_class == null) { - var any_class = (Class) root_symbol.scope.lookup ("any"); - if (cl != any_class) { - var object_class = (Class) root_symbol.scope.lookup ("Dova").scope.lookup ("Object"); - cl.add_base_type (new ObjectType (object_class)); - cl.base_class = object_class; - } - } - } - current_scope = current_scope.parent_scope; } @@ -122,14 +110,6 @@ public class Vala.SymbolResolver : CodeVisitor { } } - if (context.profile == Profile.DOVA) { - // all interfaces require Object - if (iface.get_prerequisites ().size == 0) { - var object_class = (Class) root_symbol.scope.lookup ("Dova").scope.lookup ("Object"); - iface.add_prerequisite (new ObjectType (object_class)); - } - } - current_scope = current_scope.parent_scope; } @@ -483,18 +463,6 @@ public class Vala.SymbolResolver : CodeVisitor { tmpl.accept_children (this); } - public override void visit_list_literal (ListLiteral lit) { - lit.accept_children (this); - } - - public override void visit_set_literal (SetLiteral lit) { - lit.accept_children (this); - } - - public override void visit_map_literal (MapLiteral lit) { - lit.accept_children (this); - } - public override void visit_tuple (Tuple tuple) { tuple.accept_children (this); } diff --git a/vala/valatemplate.vala b/vala/valatemplate.vala index d11c0c87c..5e27a7b8e 100644 --- a/vala/valatemplate.vala +++ b/vala/valatemplate.vala @@ -72,18 +72,11 @@ public class Vala.Template : Expression { } else { expr = stringify (expression_list[0]); if (expression_list.size > 1) { - if (context.profile == Profile.DOVA) { - // varargs concat not yet supported - for (int i = 1; i < expression_list.size; i++) { - expr = new BinaryExpression (BinaryOperator.PLUS, expr, stringify (expression_list[i]), source_reference); - } - } else { - var concat = new MethodCall (new MemberAccess (expr, "concat", source_reference), source_reference); - for (int i = 1; i < expression_list.size; i++) { - concat.add_argument (stringify (expression_list[i])); - } - expr = concat; + var concat = new MethodCall (new MemberAccess (expr, "concat", source_reference), source_reference); + for (int i = 1; i < expression_list.size; i++) { + concat.add_argument (stringify (expression_list[i])); } + expr = concat; } } expr.target_type = target_type; diff --git a/vala/valatuple.vala b/vala/valatuple.vala index 852215a4e..d35795a39 100644 --- a/vala/valatuple.vala +++ b/vala/valatuple.vala @@ -71,23 +71,9 @@ public class Vala.Tuple : Expression { checked = true; - if (context.profile != Profile.DOVA) { - Report.error (source_reference, "tuples are not supported"); - error = true; - return false; - } - - value_type = new ObjectType ((Class) context.root.scope.lookup ("Dova").scope.lookup ("Tuple")); - value_type.value_owned = true; - - foreach (var expr in expression_list) { - if (!expr.check (context)) { - return false; - } - value_type.add_type_argument (expr.value_type.copy ()); - } - - return !error; + Report.error (source_reference, "tuples are not supported"); + error = true; + return false; } public override void emit (CodeGenerator codegen) {