contrib/objcwrapper: intro objcwrapper base code
authorArthur Delamare <arthur.delamare@viacesi.fr>
Mon, 13 Apr 2015 22:42:20 +0000 (18:42 -0400)
committerAlexis Laferrière <alexis.laf@xymus.net>
Fri, 21 Aug 2015 19:03:24 +0000 (15:03 -0400)
Signed-off-by: Arthur Delamare <arthur.delamare@viacesi.fr>
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

contrib/objcwrapper/grammar/objc.sablecc [new file with mode: 0644]
contrib/objcwrapper/src/objc_generator.nit [new file with mode: 0644]
contrib/objcwrapper/src/objc_model.nit [new file with mode: 0644]
contrib/objcwrapper/src/objc_visitor.nit [new file with mode: 0644]
contrib/objcwrapper/src/objcwrapper.nit [new file with mode: 0644]

diff --git a/contrib/objcwrapper/grammar/objc.sablecc b/contrib/objcwrapper/grammar/objc.sablecc
new file mode 100644 (file)
index 0000000..50a78fd
--- /dev/null
@@ -0,0 +1,337 @@
+/* Grammar for Objective-C header files */
+Grammar objc;
+
+Lexer
+    upper = 'A'..'Z';
+    lower = 'a'..'z';
+    letter = upper | lower;
+    digit = '0'..'9';
+
+    comma = ',';
+    lpar = '(';
+    rpar = ')';
+    star = '*';
+
+    string = '"' (Any - '"')* '"';
+    class = upper (letter | '_' | digit)*;
+    id = lower (letter | '_' | digit)*;
+
+    private = '_' (letter | digit)+;
+    num = digit+;
+    macro_name = '__' (letter | '_')+;
+    num_typed = num upper+;
+    hexadecimal = '0x' (letter | digit)+;
+    pointer = star+;
+
+    blank = (' ' | '\t' | '\n')+;
+    comments = ('#' (Any - '\n')*);
+
+Parser
+    Ignored blank, comments;
+
+    prog = lines*;
+
+    lines =
+        {class:} '@class' classes ';' |
+        {protocol:} protocol |
+        {attribute:} attribute |
+        {static:} static |
+        {structure:} structure |
+        {interface:} '@interface' class interface? inheritance? protocols? instance_variables? interface_block* '@end' |
+        {line:} line;
+
+    interface_block =
+        {line:} line |
+        {instance:} instance_declaration;
+
+    line =
+        {library_extern_declaration:} library_extern_declaration |
+        {typedef:} typedef |
+        {extern:} extern |
+        {enum:} 'enum' '{' params '}' attribute? ';';
+
+    typedef =
+        {variable:} 'typedef' 'struct'? declaration ';' |
+        {method:} 'typedef' type method ';' |
+        {structure:} 'typedef' structure |
+        {anonymous:} 'typedef' type anonymous ';';
+
+    instance_declaration =
+        {signature:} signature_block |
+        {property:} property_declaration;
+
+    property_declaration =
+        {property:} optional_method? '@property' property_attribute? property attribute* ';';
+
+    property_attribute =
+        {attribute:} lpar params rpar;
+
+    interface =
+        {interface:} lpar params? rpar;
+
+    library_extern_declaration =
+        {simple:} 'UIKIT_EXTERN' type pointer? 'const'? term attribute? ';' |
+        {method:} 'UIKIT_EXTERN' type method? attribute? ';';
+
+    protocol =
+        {declaration:} '@protocol' type additional_type* ';' |
+        {construction:} '@protocol' type protocols? protocol_block+ '@end';
+
+    additional_type =
+        {type:} comma type;
+
+    protocol_block =
+        {signature:} signature_block |
+        {property:} property_declaration;
+
+    signature_block =
+        {signature:} optional_method? scope signature_return_type? signature+ attribute_list? ';';
+
+    signature_return_type =
+        {return:} lpar type pointer? function_pointer? protocols? rpar;
+
+    optional_method =
+        {required:} '@required' |
+        {optional:} '@optional';
+
+    method =
+        {call:} pointer? term lpar args rpar |
+        {declaration:} pointer? term lpar declarations rpar;
+
+    attribute_list =
+        {attr:} attribute+;
+
+    attribute =
+        {availability:} '__attribute__' lpar lpar 'availability' lpar params rpar rpar rpar |
+        {visibility:} '__attribute__' lpar lpar 'visibility' lpar term rpar rpar rpar |
+        {objc_gc:} '__attribute__' lpar lpar 'objc_gc' lpar term rpar rpar rpar |
+        {attribute_id:} '__attribute__' lpar lpar term rpar rpar |
+        {attribute_method:} '__attribute__' lpar lpar method rpar rpar;
+
+    extern =
+        {method:} 'extern' type method attribute? ';' |
+        {simple:} 'extern' type pointer? 'const'? term attribute? ';';
+
+    static =
+        {method:} 'static' 'inline' type method attribute? ';' |
+        {attr:} 'static' '__inline__' attribute+ type method attribute? ';';
+
+    scope =
+        {class:} '+' |
+        {instance:} '-';
+
+    signature =
+        {named:} [left:]term ':' lpar signature_type rpar attribute? [right:]term |
+        {single:} term |
+        {comma:} comma '...' |
+        {macro:} macro_name;
+
+    signature_type =
+        {anonymous:} type anonymous |
+        {table:} type protocols? '[]' |
+        {pointer:} type pointer |
+        {unsigned:} unsigned pointer |
+        {protocol:} type protocols |
+        {function_pointer:} function_pointer |
+        {normal:} type;
+
+    anonymous =
+        {method:} lpar '^' term? rpar lpar declarations? rpar |
+        {inception:} lpar '^' term? rpar lpar type lpar '^' term? rpar lpar type rpar rpar;
+
+    property =
+        {property:} type protocols? pointer? [left:]term [right:]term? |
+        {anonymous:} type anonymous |
+        {function_pointer:} function_pointer;
+
+    type =
+        {type:} type_annotation? unsigned? data_type;
+
+    type_annotation =
+        {const:} 'const' |
+        {in:} 'in' |
+        {out:} 'out' |
+        {inout:} 'inout' |
+        {bycopy:} 'bycopy' |
+        {byref:} 'byref';
+
+    unsigned =
+        {u:} 'unsigned' |
+        {s:} 'signed';
+
+    data_type =
+        {more:} more_type |
+        {otype:} class;
+
+    more_type =
+        {stype:} specific_type |
+        {ptype:} primitive_type;
+
+    specific_type =
+        {uui:} 'uuid_t' |
+        {i:} 'id' |
+        {b:} '_Bool' |
+        {pth:} 'pthread_mutex_t' |
+        {ds:} 'dispatch_semaphore_t' |
+        {dq:} 'dispatch_queue_t' |
+        {val:} 'va_list' |
+        {identityref:} 'SecIdentityRef' |
+        {trustref:} 'SecTrustRef' |
+        {class:} 'Class' |
+        {protocol:} 'Protocol' |
+        {v:} 'void';
+
+    primitive_type =
+        {ui8:} 'uint8_t' |
+        {ui16:} 'uint16_t' |
+        {ui32:} 'uint32_t' |
+        {ui64:} 'uint64_t' |
+        {i8:} 'int8_t' |
+        {i16:} 'int16_t' |
+        {i32:} 'int32_t' |
+        {i64:} 'int64_t' |
+        {uc:} 'unichar' |
+        {c:} 'char' |
+        {s:} 'short' |
+        {si:} 'short int' |
+        {i:} 'int' |
+        {l:} 'long' |
+        {li:} 'long int' |
+        {ll:} 'long long' |
+        {lli:} 'long long int' |
+        {f:} 'float' |
+        {d:} 'double' |
+        {ld:} 'long double';
+
+    classe =
+        {class:} class |
+        {protocol:} 'Protocol';
+
+    classes =
+        {classes:} classe additional*;
+
+    protocols =
+        {protocols:} '<' classe additional* '>';
+
+    inheritance =
+        {add:} ':' classe additional*;
+
+    additional =
+        {add:} comma classe;
+
+    declarations =
+        {declarations:} declaration additional_declaration*;
+
+    additional_declaration =
+        {add:} comma declaration;
+
+    declaration =
+        {pointer:} type protocols? attribute? pointer? term? '[]'? |
+        {typedef:} type primitive_type |
+        {function_pointer:} function_pointer |
+        {comma:} '...';
+
+    declaration_variable_instance =
+        {unsigned:} type_annotation? unsigned more_type? protocols? attribute? pointer? term '[]'? |
+        {data_type:} type_annotation? data_type protocols? attribute? pointer? term? '[]'?;
+
+    instance_variables =
+        {instance:} '{' instance_variable* '}';
+
+    scope_instance_variable =
+        {package:} '@package' |
+        {public:} '@public' |
+        {private:} '@private' |
+        {protected:} '@protected';
+
+    instance_variable =
+        {scope:} scope_instance_variable |
+        {variable:} attribute? declaration_variable_instance bit_field? additional_variable* ';' |
+        {anonymous:} declaration_variable_instance anonymous ';' |
+        {structure:} structure |
+        {union:} union;
+
+    additional_variable =
+        {add} comma term bit_field?;
+
+    function_pointer =
+        {type:} type pointer? lpar pointer term? rpar lpar declarations rpar;
+
+    union =
+        {name:} 'union' '{' structure_params+ '}' term ';';
+
+    structure =
+        {name:} 'struct' structure_core term ';' |
+        {type:} 'struct' type structure_core term? ';' |
+        {private:} 'struct' private structure_core? term? ';';
+
+    structure_core =
+        {core:} '{' structure_params+ '}';
+
+    structure_params =
+        {value:} declaration bit_field? ';' |
+        {structure:} structure;
+
+    params =
+        {params:} param additional_params*;
+
+    additional_params =
+        {add:} comma param?;
+
+    param =
+        {id:} term |
+        {bitwise:} term '=' bitwise |
+        {term:} term '=' pointer? term+ |
+        {attr:} term attribute |
+        {attrterm:} term attribute '=' term |
+        {attrbitwise:} term attribute '=' bitwise;
+
+    args =
+        {args:} arg additional_arg*;
+
+    additional_arg =
+        {add:} comma arg;
+
+    arg =
+        {num:} num |
+        {macro:} macro_name;
+
+    bitwise =
+        {rterm:} bitwise_operator_not? term bitwise_operator bitwise_operator_not? term |
+        {num:} lpar bitwise_operator_not? term rpar |
+        {term:} lpar bitwise_operator_not? term additional_bitwise+ rpar arithmetic?;
+
+    bitwise_operator =
+        {left_shift:} '<<' |
+        {right_shift:} '>>' |
+        {and:} '&' |
+        {or:} '|' |
+        {xor:} '^';
+
+    bitwise_operator_not =
+        {not:} '~';
+
+    additional_bitwise =
+        {add:} bitwise_operator bitwise_operator_not? term;
+
+    bit_field =
+        {value:} ':' num;
+
+    arithmetic =
+        {add:} '+' num |
+        {minus:} '-' num |
+        {star:} pointer num |
+        {divide:} '/' num;
+
+    term =
+        {num_typed:} '-'? num_typed |
+        {private:} private |
+        {num:} num |
+        {negative:} '-' num |
+        {float:} num '.' num |
+        {string:} string |
+        {hexadecimal:} hexadecimal |
+        {class:} class |
+        {var:} id |
+        {private_table:} private '[' lpar? num rpar? ']' |
+        {table:} id '[' lpar? num rpar? ']';
diff --git a/contrib/objcwrapper/src/objc_generator.nit b/contrib/objcwrapper/src/objc_generator.nit
new file mode 100644 (file)
index 0000000..5f8fd5c
--- /dev/null
@@ -0,0 +1,181 @@
+module objc_generator
+
+import objc_model
+
+class CodeGenerator
+       fun generator(classes: Array[nullable ObjcClass]) do
+               var init_with_alloc = true
+               for classe in classes do
+                       var file = new FileWriter.open(classe.name + ".nit")
+                       nit_class_generator(classe, file, init_with_alloc)
+                       file.close
+               end
+       end
+
+       fun type_convertor(type_word: String): String do
+               var types = new HashMap[String, String]
+               types["char"] = "Byte"
+               types["short"] = "Int"
+               types["short int"] = "Int"
+               types["int"] = "Int"
+               types["long"] = "Int"
+               types["long int"] = "Int"
+               types["long long"] = "Int"
+               types["long long int"] = "Int"
+               types["float"] = "Float"
+               types["double"] = "Float"
+               types["long double"] = "Float"
+
+               types["NSUInteger"] = "Int"
+               types["BOOL"] = "Bool"
+               types["id"] = "NSObject"
+
+               if types.has_key(type_word) then
+                       return types[type_word]
+               else
+                       return type_word
+               end
+       end
+
+       fun nit_class_generator(classe: nullable ObjcClass, file: FileWriter, init_with_alloc: Bool) do
+               var commented_methods = new Array[ObjcMethod]
+               file.write "import cocoa::foundation\n\n"
+               file.write("extern class " + classe.name + """ in "ObjC" `{ """ + classe.name  + """ * `}\n""")
+               for super_name in classe.super_names do
+                       file.write("""  super """ + super_name + "\n")
+               end
+               if classe.super_names.is_empty then file.write("""      super NSObject\n""")
+               new_nit_generator(classe, file, init_with_alloc)
+               file.write("\n")
+               for attribute in classe.attributes do
+                       nit_attribute_generator(attribute, file)
+               end
+               for method in classe.methods do
+                       if method.is_commented then
+                               commented_methods.add(method)
+                       else
+                               if init_with_alloc and method.params.first.name.has("init") then continue
+                               file.write("""  """)
+                               nit_method_generator(method, file, init_with_alloc)
+                               file.write(""" in "ObjC" `{\n           """)
+                               objc_method_generator(method, file)
+                               file.write("""  `}""")
+                               if method != classe.methods.last then file.write("\n\n")
+                       end
+               end
+               for commented_method in commented_methods do
+                       if commented_method == commented_methods.first then file.write("\n")
+                       file.write("""  #""")
+                       nit_method_generator(commented_method, file, init_with_alloc)
+                       if commented_method != commented_methods.last then file.write("\n")
+               end
+               file.write("\nend")
+       end
+
+       fun new_nit_generator(classe: nullable ObjcClass, file: FileWriter, init_with_alloc: Bool) do
+               if init_with_alloc then
+                       for method in classe.methods do
+                               if method.params.first.name.has("init") and not method.is_commented then
+                                       file.write """\n        """
+                                       if method.params.first.name == "init" then
+                                               file.write "new"
+                                       else
+                                               nit_method_generator(method, file, init_with_alloc)
+                                       end
+                                       file.write """ in "ObjC" `{\n"""
+                                       new_alloc_init_objc_generator(classe.name, method, file)
+                                       file.write """  `}\n"""
+                               end
+                       end
+               else
+                       file.write """\n        new in "ObjC"`{\n"""
+                       new_objc_generator(classe, file)
+                       file.write """  `}\n"""
+               end
+       end
+
+       fun nit_attribute_generator(attribute: ObjcAttribute, file: FileWriter) do
+               nit_attribute_setter_generator(attribute, file)
+               file.write "\n"
+       end
+
+       fun nit_attribute_setter_generator(attribute: ObjcAttribute, file: FileWriter) do
+               file.write("""  fun """ + attribute.name.to_snake_case + ": " + type_convertor(attribute.return_type))
+               file.write """ in "ObjC" `{\n"""
+               objc_attribute_setter_generator(attribute, file)
+               file.write """  `}\n"""
+       end
+
+       fun nit_attribute_getter_generator(attribute: ObjcAttribute, file: FileWriter) do
+               file.write("""  fun """ + attribute.name.to_snake_case + "=(value: " + type_convertor(attribute.return_type) + ")")
+               file.write " in \"ObjC\" `\{\n"
+               objc_attribute_getter_generator(attribute, file)
+               file.write """  `}\n"""
+       end
+
+       fun nit_method_generator(method: ObjcMethod, file: FileWriter, init_with_alloc: Bool) do
+               var name = ""
+               for param in method.params do
+                       name += param.name[0].to_upper.to_s + param.name.substring_from(1)
+                       name = name.to_snake_case
+               end
+               if name.has("init") and init_with_alloc then
+                       file.write "new "
+               else
+                       if not init_with_alloc and name == "init" then name = "init_0"
+                       file.write "fun "
+               end
+               file.write(name)
+               for param in method.params do
+                       if param == method.params.first and not param.is_single then
+                               file.write("(" + param.variable_name + ": " + type_convertor(param.return_type))
+                       end
+                       if param != method.params.first and not param.is_single then
+                               file.write(", " + param.variable_name + ": " + type_convertor(param.return_type))
+                       end
+                       if param == method.params.last and not param.is_single then
+                               file.write ")"
+                       end
+               end
+               if method.return_type != "void" and not method.params.first.name.has("init") then file.write(": " + type_convertor(method.return_type))
+       end
+
+       fun new_alloc_init_objc_generator(classe_name: String, method: ObjcMethod, file: FileWriter) do
+               file.write("""          return [[""" + classe_name + " alloc] ")
+               for param in method.params do
+                       if not param.is_single then
+                               file.write(param.name + ":" + param.variable_name)
+                               if not param == method.params.last then file.write(" ")
+                       else
+                               file.write param.name
+                       end
+               end
+               file.write "];\n"
+       end
+
+       fun new_objc_generator(classe: nullable ObjcClass, file: FileWriter) do
+               file.write("""          return [""" + classe.name + " alloc];\n")
+       end
+
+       fun objc_attribute_setter_generator(attribute: ObjcAttribute, file: FileWriter) do
+               file.write("""          return [self """ + attribute.name + "];\n")
+       end
+
+       fun objc_attribute_getter_generator(attribute: ObjcAttribute, file: FileWriter) do
+               file.write("""          self.""" + attribute.name + " = value;\n")
+       end
+
+       fun objc_method_generator(method: ObjcMethod, file: FileWriter) do
+               if method.return_type != "void" then file.write("return ")
+               file.write "[self "
+               for param in method.params do
+                       if not param.is_single then
+                               file.write(param.name + ":" + param.variable_name)
+                               if not param == method.params.last then file.write " "
+                       else
+                               file.write(param.name)
+                       end
+               end
+               file.write "];\n"
+       end
+end
diff --git a/contrib/objcwrapper/src/objc_model.nit b/contrib/objcwrapper/src/objc_model.nit
new file mode 100644 (file)
index 0000000..2ade394
--- /dev/null
@@ -0,0 +1,40 @@
+module objc_model
+
+class ObjcModel
+       var classes = new Array[ObjcClass]
+end
+
+class ObjcClass
+       var super_names = new Array[String]
+       var name: String
+       var attributes = new Array[ObjcAttribute]
+       var methods = new Array[ObjcMethod]
+end
+
+class ObjcMethod
+       super Property
+
+       var scope: Char is noinit, writable
+       var params = new Array[Param]
+       var return_type: String is noinit, writable
+end
+
+class ObjcAttribute
+       super Property
+
+       var name: String is noinit, writable
+       var return_type: String is noinit, writable
+end
+
+class Property
+       var is_commented = false is writable
+end
+
+class Param
+       var name: String is noinit, writable
+       var return_type: String is noinit, writable
+       var variable_name: String is noinit, writable
+       var is_table = false is writable
+       var is_pointer = false is writable
+       var is_single = false is writable
+end
diff --git a/contrib/objcwrapper/src/objc_visitor.nit b/contrib/objcwrapper/src/objc_visitor.nit
new file mode 100644 (file)
index 0000000..a73d528
--- /dev/null
@@ -0,0 +1,566 @@
+module objc_visitor
+
+import objc_model
+import objc_parser
+
+class Interpretor
+       super Visitor
+
+       var is_variable = false
+       var is_method = false
+       var is_parameter_name = false
+       var class_objc: nullable ObjcClass = null
+       var method_objc: ObjcMethod is noinit
+       var attribute_objc: ObjcAttribute is noinit
+       var param: Param is noinit
+       var model = new ObjcModel
+
+       redef fun visit(n) do n.accept_objc(self)
+end
+
+redef class Node
+       fun accept_objc(v: Interpretor) do visit_children(v)
+end
+
+redef class Nlines
+       redef fun accept_objc(v) do
+       end
+end
+
+redef class Nlines_interface
+       redef fun accept_objc(v) do
+               var interface_block = n_interface_block
+               var inheritance_block = n_inheritance
+               v.class_objc = null
+               if interface_block != null then
+                       for class_objc in v.model.classes do
+                               if class_objc.name == n_class.text then
+                                       v.class_objc = class_objc
+                               end
+                       end
+                       if v.class_objc == null then
+                               v.class_objc = new ObjcClass(n_class.text)
+                               v.model.classes.add(v.class_objc)
+                       end
+                       if inheritance_block != null then v.enter_visit(inheritance_block)
+                       v.enter_visit(interface_block)
+               end
+       end
+end
+
+redef class Ninheritance_add
+       redef fun accept_objc(v) do
+               var additional = n_additional
+               v.enter_visit(n_classe)
+               if additional != null then v.enter_visit(additional)
+       end
+end
+
+redef class Nclasse_class
+       redef fun accept_objc(v) do
+               v.class_objc.super_names.add(n_class.text)
+       end
+end
+
+redef class Nadditional_add
+       redef fun accept_objc(v) do
+               v.enter_visit(n_classe)
+       end
+end
+
+redef class Ninterface_block_instance
+       redef fun accept_objc(v) do
+               v.enter_visit(n_instance_declaration)
+       end
+end
+
+redef class Ninstance_declaration_signature
+       redef fun accept_objc(v) do
+               v.enter_visit(n_signature_block)
+       end
+end
+
+redef class Ninstance_declaration_property
+       redef fun accept_objc(v) do
+               v.enter_visit(n_property_declaration)
+       end
+end
+
+redef class Nproperty_declaration_property
+       redef fun accept_objc(v) do
+               v.enter_visit(n_property)
+       end
+end
+
+redef class Nsignature_block_signature
+       redef fun accept_objc(v) do
+               if n_signature.children.to_s.has("signature_named") or n_signature.children.to_s.has("signature_single") then
+                       v.method_objc = new ObjcMethod
+
+                       v.enter_visit(n_scope)
+                       v.is_method = true
+                       var signature_return_type = n_signature_return_type
+                       if signature_return_type != null then v.enter_visit(signature_return_type)
+                       v.is_method = false
+                       v.enter_visit(n_signature)
+
+                       v.class_objc.methods.add(v.method_objc)
+               end
+       end
+end
+
+redef class Nscope_instance
+       redef fun accept_objc(v) do
+               v.method_objc.scope = '-'
+       end
+end
+
+redef class Nscope_class
+       redef fun accept_objc(v) do
+               v.method_objc.scope = '+'
+       end
+end
+
+redef class Nsignature_return_type_return
+       redef fun accept_objc(v) do
+               v.enter_visit(n_type)
+       end
+end
+
+redef class Nsignature_named
+       redef fun accept_objc(v) do
+               v.param = new Param
+
+               v.enter_visit(n_left)
+               v.is_parameter_name = true
+               v.enter_visit(n_right)
+               v.is_parameter_name = false
+               v.enter_visit(n_signature_type)
+
+               v.method_objc.params.add(v.param)
+       end
+end
+
+redef class Nsignature_single
+       redef fun accept_objc(v) do
+               v.param = new Param
+               v.param.is_single = true
+               v.enter_visit(n_term)
+               v.method_objc.params.add(v.param)
+       end
+end
+
+redef class Nsignature_type_anonymous
+       redef fun accept_objc(v) do
+               v.enter_visit(n_type)
+               v.method_objc.is_commented = true
+       end
+end
+
+redef class Nsignature_type_table
+       redef fun accept_objc(v) do
+               v.enter_visit(n_type)
+               v.param.is_table = true
+       end
+end
+
+redef class Nsignature_type_pointer
+       redef fun accept_objc(v) do
+               v.enter_visit(n_type)
+               v.param.is_pointer = true
+       end
+end
+
+redef class Nsignature_type_unsigned
+       redef fun accept_objc(v) do
+               v.method_objc.is_commented = true
+               v.param.is_pointer = true
+       end
+end
+
+redef class Nsignature_type_protocol
+       redef fun accept_objc(v) do
+               v.enter_visit(n_type)
+               v.method_objc.is_commented = true
+       end
+end
+
+redef class Nsignature_type_normal
+       redef fun accept_objc(v) do
+               v.enter_visit(n_type)
+       end
+end
+
+redef class Nterm_private
+       redef fun accept_objc(v) do
+               if v.is_parameter_name then
+                       v.param.variable_name = n_private.text
+               else if v.is_variable then
+                       v.attribute_objc.name = n_private.text
+               else
+                       v.param.name = n_private.text
+               end
+       end
+end
+
+redef class Nterm_class
+       redef fun accept_objc(v) do
+               if v.is_parameter_name then
+                       v.param.variable_name = n_class.text
+               else if v.is_variable then
+                       v.attribute_objc.name = n_class.text
+               else
+                       v.param.name = n_class.text
+               end
+       end
+end
+
+redef class Nterm_var
+       redef fun accept_objc(v) do
+               if v.is_parameter_name then
+                       v.param.variable_name = n_id.text
+               else if v.is_variable then
+                       v.attribute_objc.name = n_id.text
+               else
+                       v.param.name = n_id.text
+               end
+       end
+end
+
+redef class Nproperty_property
+       redef fun accept_objc(v) do
+               var protocol = n_protocols
+               if protocol == null then
+                       v.is_variable = true
+                       v.attribute_objc = new ObjcAttribute
+                       v.enter_visit(n_left)
+                       v.enter_visit(n_type)
+                       v.class_objc.attributes.add(v.attribute_objc)
+                       v.is_variable = false
+               end
+       end
+end
+
+redef class Ntype_type
+       redef fun accept_objc(v) do
+               v.enter_visit(n_data_type)
+       end
+end
+
+redef class Ndata_type_more
+       redef fun accept_objc(v) do
+               v.enter_visit(n_more_type)
+       end
+end
+
+redef class Ndata_type_otype
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = n_class.text
+               else if v.is_method then
+                       v.method_objc.return_type = n_class.text
+               else
+                       v.param.return_type = n_class.text
+               end
+       end
+end
+
+redef class Nmore_type_stype
+       redef fun accept_objc(v) do
+               v.enter_visit(n_specific_type)
+       end
+end
+
+redef class Nmore_type_ptype
+       redef fun accept_objc(v) do
+               v.enter_visit(n_primitive_type)
+       end
+end
+
+redef class Nspecific_type_i
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "id"
+               else if v.is_method then
+                       v.method_objc.return_type = "id"
+               else
+                       v.param.return_type = "id"
+               end
+       end
+end
+
+redef class Nspecific_type_b
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "Bool"
+               else if v.is_method then
+                       v.method_objc.return_type = "Bool"
+               else
+                       v.param.return_type = "Bool"
+               end
+       end
+end
+
+redef class Nspecific_type_val
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "va_list"
+               else if v.is_method then
+                       v.method_objc.return_type = "va_list"
+               else
+                       v.param.return_type = "va_list"
+               end
+       end
+end
+
+redef class Nspecific_type_v
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "void"
+               else if v.is_method then
+                       v.method_objc.return_type = "void"
+               else
+                       v.param.return_type = "void"
+               end
+       end
+end
+
+redef class Nprimitive_type_ui8
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "uint8_t"
+               else if v.is_method then
+                       v.method_objc.return_type = "uint8_t"
+               else
+                       v.param.return_type = "uint8_t"
+               end
+       end
+end
+
+redef class Nprimitive_type_ui16
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "uint16_t"
+               else if v.is_method then
+                       v.method_objc.return_type = "uint16_t"
+               else
+                       v.param.return_type = "uint16_t"
+               end
+       end
+end
+
+redef class Nprimitive_type_ui32
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "uint32_t"
+               else if v.is_method then
+                       v.method_objc.return_type = "uint32_t"
+               else
+                       v.param.return_type = "uint32_t"
+               end
+       end
+end
+
+redef class Nprimitive_type_ui64
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "uint64_t"
+               else if v.is_method then
+                       v.method_objc.return_type = "uint64_t"
+               else
+                       v.param.return_type = "uint64_t"
+               end
+       end
+end
+
+redef class Nprimitive_type_i8
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "int8_t"
+               else if v.is_method then
+                       v.method_objc.return_type = "int8_t"
+               else
+                       v.param.return_type = "int8_t"
+               end
+       end
+end
+
+redef class Nprimitive_type_i16
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "int16_t"
+               else if v.is_method then
+                       v.method_objc.return_type = "int16_t"
+               else
+                       v.param.return_type = "int16_t"
+               end
+       end
+end
+
+redef class Nprimitive_type_i32
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "int32_t"
+               else if v.is_method then
+                       v.method_objc.return_type = "int32_t"
+               else
+                       v.param.return_type = "int32_t"
+               end
+       end
+end
+
+redef class Nprimitive_type_i64
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "int64_t"
+               else if v.is_method then
+                       v.method_objc.return_type = "int64_t"
+               else
+                       v.param.return_type = "int64_t"
+               end
+       end
+end
+
+redef class Nprimitive_type_uc
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "unichar"
+               else if v.is_method then
+                       v.method_objc.return_type = "unichar"
+               else
+                       v.param.return_type = "unichar"
+               end
+       end
+end
+
+redef class Nprimitive_type_c
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "char"
+               else if v.is_method then
+                       v.method_objc.return_type = "char"
+               else
+                       v.param.return_type = "char"
+               end
+       end
+end
+
+redef class Nprimitive_type_s
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "short"
+               else if v.is_method then
+                       v.method_objc.return_type = "short"
+               else
+                       v.param.return_type = "short"
+               end
+       end
+end
+
+redef class Nprimitive_type_si
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "short int"
+               else if v.is_method then
+                       v.method_objc.return_type = "short int"
+               else
+                       v.param.return_type = "short int"
+               end
+       end
+end
+
+redef class Nprimitive_type_i
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "int"
+               else if v.is_method then
+                       v.method_objc.return_type = "int"
+               else
+                       v.param.return_type = "int"
+               end
+       end
+end
+
+redef class Nprimitive_type_l
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "long"
+               else if v.is_method then
+                       v.method_objc.return_type = "long"
+               else
+                       v.param.return_type = "long"
+               end
+       end
+end
+
+redef class Nprimitive_type_li
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "long int"
+               else if v.is_method then
+                       v.method_objc.return_type = "long int"
+               else
+                       v.param.return_type = "long int"
+               end
+       end
+end
+
+redef class Nprimitive_type_ll
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "long long"
+               else if v.is_method then
+                       v.method_objc.return_type = "long long"
+               else
+                       v.param.return_type = "long long"
+               end
+       end
+end
+
+redef class Nprimitive_type_lli
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "long long int"
+               else if v.is_method then
+                       v.method_objc.return_type = "long long int"
+               else
+                       v.param.return_type = "long long int"
+               end
+       end
+end
+
+redef class Nprimitive_type_f
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "float"
+               else if v.is_method then
+                       v.method_objc.return_type = "float"
+               else
+                       v.param.return_type = "float"
+               end
+       end
+end
+
+redef class Nprimitive_type_d
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "double"
+               else if v.is_method then
+                       v.method_objc.return_type = "double"
+               else
+                       v.param.return_type = "double"
+               end
+       end
+end
+
+redef class Nprimitive_type_ld
+       redef fun accept_objc(v) do
+               if v.is_variable then
+                       v.attribute_objc.return_type = "long double"
+               else if v.is_method then
+                       v.method_objc.return_type = "long double"
+               else
+                       v.param.return_type = "long double"
+               end
+       end
+end
diff --git a/contrib/objcwrapper/src/objcwrapper.nit b/contrib/objcwrapper/src/objcwrapper.nit
new file mode 100644 (file)
index 0000000..a714a4d
--- /dev/null
@@ -0,0 +1,24 @@
+module objcwrapper
+
+import objc_visitor
+import objc_model
+import objc_generator
+
+import nitcc_runtime
+import objc_lexer
+import objc_parser
+
+var v = new Interpretor
+var g = new CodeGenerator
+
+for arg in args do
+       var file = new FileReader.open(arg)
+       var lexer = new Lexer_objc(file.read_all)
+       var parser = new Parser_objc
+       var tokens = lexer.lex
+       parser.tokens.add_all(tokens)
+       v.enter_visit(parser.parse)
+       file.close
+end
+
+g.generator v.model.classes