1
0
mirror of https://github.com/twiglet/cs2j.git synced 2025-01-18 13:15:17 +01:00

generate cast methods, implement TYPEOF_expr_TYPE

This commit is contained in:
Kevin Glynn 2011-01-21 16:34:23 +01:00
parent 4c882a08e2
commit cf3d57a3bd
3 changed files with 84 additions and 44 deletions

View File

@ -321,14 +321,14 @@ namespace RusticiSoftware.Translator.CLR
public override string mkJava() {
string constructorName = "CONSTRUCTOR";
if (SurroundingTypeName != null) {
if (!String.IsNullOrEmpty(SurroundingTypeName)) {
constructorName = SurroundingTypeName.Substring(SurroundingTypeName.LastIndexOf('.') + 1);
}
return "new " + constructorName + mkJavaParams(Params);
}
public override string[] mkImports() {
if (SurroundingTypeName != null) {
if (!String.IsNullOrEmpty(SurroundingTypeName)) {
return new string[] {SurroundingTypeName};
}
else {
@ -454,12 +454,12 @@ namespace RusticiSoftware.Translator.CLR
public override string mkJava() {
StringBuilder methStr = new StringBuilder();
if (IsStatic) {
if (SurroundingTypeName != null) {
methStr.Append(SurroundingTypeName.Substring(SurroundingTypeName.LastIndexOf('.') + 1) + ".");
}
else {
methStr.Append("TYPENAME.");
}
if (!String.IsNullOrEmpty(SurroundingTypeName)) {
methStr.Append(SurroundingTypeName.Substring(SurroundingTypeName.LastIndexOf('.') + 1) + ".");
}
else {
methStr.Append("TYPENAME.");
}
}
else {
methStr.Append("${this}.");
@ -565,11 +565,11 @@ namespace RusticiSoftware.Translator.CLR
}
public override string[] mkImports() {
if (From == null || To == null) {
return null;
if (!String.IsNullOrEmpty(SurroundingTypeName)) {
return new string[] {SurroundingTypeName};
}
else {
return new string[] {"CS2JNet." + From};
return null;
}
}
@ -578,7 +578,13 @@ namespace RusticiSoftware.Translator.CLR
return null;
}
else {
return From.Substring(From.LastIndexOf('.') + 1) + ".__cast_" + To.Replace('.','_') + "(${expr})";
if (!String.IsNullOrEmpty(SurroundingTypeName)) {
return SurroundingTypeName.Substring(SurroundingTypeName.LastIndexOf('.') + 1) + ".__castto_" + To.Replace('.','_') + "(${expr})";
}
else
{
return "__cast_" + To.Replace('.','_') + "(${expr})";
}
}
}

View File

@ -147,6 +147,13 @@ scope SymTab {
return (CommonTree)adaptor.RulePostProcessing(root);
}
protected CommonTree wrapTypeOfType(TypeRepTemplate t, IToken tok) {
CommonTree root = (CommonTree)adaptor.Nil;
root = (CommonTree)adaptor.BecomeRoot((CommonTree)adaptor.Create(JAVAWRAPPEREXPRESSION, tok, "EXPRESSION"), root);
adaptor.AddChild(root, (CommonTree)adaptor.Create(IDENTIFIER, tok, t.Java));
return (CommonTree)adaptor.RulePostProcessing(root);
}
protected CommonTree dupTree(CommonTree t) {
return (CommonTree)adaptor.DupTree(t);
}
@ -264,7 +271,7 @@ class_member_declaration:
| ^(OPERATOR attributes? modifiers? type operator_declaration)
| ^(ENUM attributes? modifiers? enum_declaration)
| ^(DELEGATE attributes? modifiers? delegate_declaration)
| ^(CONVERSION_OPERATOR attributes? modifiers? conversion_operator_declaration)
| ^(CONVERSION_OPERATOR attributes? modifiers? conversion_operator_declaration[$attributes.tree, $modifiers.tree]) -> conversion_operator_declaration
| ^(CONSTRUCTOR attributes? modifiers? identifier formal_parameter_list? block exception*)
| ^(STATIC_CONSTRUCTOR attributes? modifiers? block)
;
@ -274,7 +281,7 @@ exception:
// rmId is the rightmost ID in an expression like fdfd.dfdsf.returnme, otherwise it is null
// used in switch labels to strip down qualified types, which Java doesn't grok
primary_expression returns [TypeRepTemplate dotNetType, String rmId]
primary_expression returns [TypeRepTemplate dotNetType, String rmId, TypeRepTemplate typeofType]
scope {
bool parentIsApply;
}
@ -303,6 +310,10 @@ scope {
}
for (int idx = 0; idx < methodRep.Params.Count; idx++) {
myMap[methodRep.Params[idx].Name] = wrapArgument($argument_list.argTrees[idx], $i2.tree.Token);
if (methodRep.Params[idx].Name.StartsWith("TYPEOF") && $argument_list.argTreeTypeofTypes[idx] != null) {
// if this argument is a typeof expression then add a TYPEOF_TYPEOF-> typeof's type mapping
myMap[methodRep.Params[idx].Name + "_TYPE"] = wrapTypeOfType($argument_list.argTreeTypeofTypes[idx], $i2.tree.Token);
}
}
ret = mkJavaWrapper(methodResult.Result.Java, myMap, $i2.tree.Token);
Imports.Add(methodResult.Result.Imports);
@ -432,7 +443,7 @@ scope {
| unchecked_expression // unchecked {...}
| default_value_expression // default
| anonymous_method_expression // delegate (int foo) {}
| typeof_expression // typeof(Foo).Name
| typeof_expression { $dotNetType = $typeof_expression.dotNetType; $typeofType = $typeof_expression.typeofType; } // typeof(Foo).Name
;
primary_expression_start returns [TypeRepTemplate dotNetType]:
@ -456,31 +467,32 @@ paren_expression:
'(' expression ')' ;
arguments:
'(' argument_list? ')' ;
argument_list returns [List<TypeRepTemplate> argTypes, List<CommonTree> argTrees]
argument_list returns [List<TypeRepTemplate> argTypes, List<CommonTree> argTrees, List<TypeRepTemplate> argTreeTypeofTypes]
@init {
$argTypes = new List<TypeRepTemplate>();
$argTrees = new List<CommonTree>();
$argTreeTypeofTypes = new List<TypeRepTemplate>();
}:
^(ARGS (argument { $argTypes.Add($argument.dotNetType); $argTrees.Add(dupTree($argument.tree)); })+);
^(ARGS (argument { $argTypes.Add($argument.dotNetType); $argTrees.Add(dupTree($argument.tree)); $argTreeTypeofTypes.Add($argument.typeofType); })+);
// 4.0
argument returns [TypeRepTemplate dotNetType]:
argument_name argument_value { $dotNetType = $argument_value.dotNetType; }
| argument_value { $dotNetType = $argument_value.dotNetType; }
argument returns [TypeRepTemplate dotNetType, TypeRepTemplate typeofType]:
argument_name argument_value { $dotNetType = $argument_value.dotNetType; $typeofType = $argument_value.typeofType; }
| argument_value { $dotNetType = $argument_value.dotNetType; $typeofType = $argument_value.typeofType; }
;
argument_name:
identifier ':';
argument_value returns [TypeRepTemplate dotNetType]:
expression { $dotNetType = $expression.dotNetType; }
| ref_variable_reference { $dotNetType = $ref_variable_reference.dotNetType; }
| 'out' variable_reference { $dotNetType = $variable_reference.dotNetType; } ;
ref_variable_reference returns [TypeRepTemplate dotNetType]:
argument_value returns [TypeRepTemplate dotNetType, TypeRepTemplate typeofType]:
expression { $dotNetType = $expression.dotNetType; $typeofType = $expression.typeofType; }
| ref_variable_reference { $dotNetType = $ref_variable_reference.dotNetType; $typeofType = $ref_variable_reference.typeofType; }
| 'out' variable_reference { $dotNetType = $variable_reference.dotNetType; $typeofType = $variable_reference.typeofType; } ;
ref_variable_reference returns [TypeRepTemplate dotNetType, TypeRepTemplate typeofType]:
'ref'
(('(' type ')') => '(' type ')' (ref_variable_reference | variable_reference) { $dotNetType = $type.dotNetType; } // SomeFunc(ref (int) ref foo)
// SomeFunc(ref (int) foo)
| v1=variable_reference { $dotNetType = $v1.dotNetType; }); // SomeFunc(ref foo)
| v1=variable_reference { $dotNetType = $v1.dotNetType; $typeofType = $v1.typeofType; }); // SomeFunc(ref foo)
// lvalue
variable_reference returns [TypeRepTemplate dotNetType]:
expression { $dotNetType = $expression.dotNetType; };
variable_reference returns [TypeRepTemplate dotNetType, TypeRepTemplate typeofType]:
expression { $dotNetType = $expression.dotNetType; $typeofType = $expression.typeofType; };
rank_specifiers:
rank_specifier+ ;
rank_specifier:
@ -501,9 +513,9 @@ member_declarator_list:
member_declarator (',' member_declarator)* ;
member_declarator:
qid ('=' expression)? ;
primary_or_array_creation_expression returns [TypeRepTemplate dotNetType, String rmId]:
primary_or_array_creation_expression returns [TypeRepTemplate dotNetType, String rmId, TypeRepTemplate typeofType]:
(array_creation_expression) => array_creation_expression
| primary_expression { $dotNetType = $primary_expression.dotNetType; $rmId = $primary_expression.rmId; }
| primary_expression { $dotNetType = $primary_expression.dotNetType; $rmId = $primary_expression.rmId; $typeofType = $primary_expression.typeofType; }
;
// new Type[2] { }
array_creation_expression:
@ -581,8 +593,8 @@ initializer_value:
///////////////////////////////////////////////////////
typeof_expression:
^('typeof' (unbound_type_name | type | 'void') ) ;
typeof_expression returns [TypeRepTemplate dotNetType, TypeRepTemplate typeofType]:
^('typeof' (unbound_type_name | type { $typeofType = $type.dotNetType; } | 'void' { $typeofType = AppEnv.Search("System.Void"); }) ) { $dotNetType = AppEnv.Search("System.Type"); };
// unbound type examples
//foo<bar<X<>>>
//bar::foo<>
@ -694,9 +706,9 @@ statement_list:
///////////////////////////////////////////////////////
// Expression Section
///////////////////////////////////////////////////////
expression returns [TypeRepTemplate dotNetType, String rmId]:
expression returns [TypeRepTemplate dotNetType, String rmId, TypeRepTemplate typeofType]:
(unary_expression assignment_operator) => assignment { $dotNetType = VoidType; }
| non_assignment_expression { $dotNetType = $non_assignment_expression.dotNetType; $rmId = $non_assignment_expression.rmId; }
| non_assignment_expression { $dotNetType = $non_assignment_expression.dotNetType; $rmId = $non_assignment_expression.rmId; $typeofType = $non_assignment_expression.typeofType; }
;
expression_list:
expression (',' expression)* ;
@ -730,12 +742,12 @@ assignment
| unary_expression assignment_operator expression ;
unary_expression returns [TypeRepTemplate dotNetType, String rmId]:
unary_expression returns [TypeRepTemplate dotNetType, String rmId, TypeRepTemplate typeofType]:
//('(' arguments ')' ('[' | '.' | '(')) => primary_or_array_creation_expression
//(cast_expression) => cast_expression
^(CAST_EXPR type unary_expression) { $dotNetType = $type.dotNetType; }
| primary_or_array_creation_expression { $dotNetType = $primary_or_array_creation_expression.dotNetType; $rmId = $primary_or_array_creation_expression.rmId; }
| primary_or_array_creation_expression { $dotNetType = $primary_or_array_creation_expression.dotNetType; $rmId = $primary_or_array_creation_expression.rmId; $typeofType = $primary_or_array_creation_expression.typeofType; }
| ^(MONOPLUS u1=unary_expression) { $dotNetType = $u1.dotNetType; }
| ^(MONOMINUS u2=unary_expression) { $dotNetType = $u2.dotNetType; }
| ^(MONONOT u3=unary_expression) { $dotNetType = $u3.dotNetType; }
@ -744,7 +756,7 @@ unary_expression returns [TypeRepTemplate dotNetType, String rmId]:
| ^(PREDEC u6=unary_expression) { $dotNetType = $u6.dotNetType; }
| ^(MONOSTAR unary_expression) { $dotNetType = ObjectType; }
| ^(ADDRESSOF unary_expression) { $dotNetType = ObjectType; }
| ^(PARENS expression) { $dotNetType = $expression.dotNetType; $rmId = $expression.rmId; }
| ^(PARENS expression) { $dotNetType = $expression.dotNetType; $rmId = $expression.rmId; $typeofType = $expression.typeofType; }
;
//cast_expression:
// '(' type ')' non_assignment_expression ;
@ -759,7 +771,7 @@ assignment_operator:
//addressof_expression:
// '&' unary_expression ;
non_assignment_expression returns [TypeRepTemplate dotNetType, String rmId]:
non_assignment_expression returns [TypeRepTemplate dotNetType, String rmId, TypeRepTemplate typeofType]:
//'non ASSIGNment'
(anonymous_function_signature '=>') => lambda_expression
| (query_expression) => query_expression
@ -786,7 +798,7 @@ non_assignment_expression returns [TypeRepTemplate dotNetType, String rmId]:
| ^('/' n12=non_assignment_expression non_assignment_expression) {$dotNetType = $n12.dotNetType; }
| ^('%' n13=non_assignment_expression non_assignment_expression) {$dotNetType = $n13.dotNetType; }
// | ^(UNARY_EXPRESSION unary_expression)
| unary_expression {$dotNetType = $unary_expression.dotNetType; $rmId = $unary_expression.rmId; }
| unary_expression {$dotNetType = $unary_expression.dotNetType; $rmId = $unary_expression.rmId; $typeofType = $unary_expression.typeofType; }
;
// ///////////////////////////////////////////////////////
@ -1172,10 +1184,15 @@ binary_operator_declarator:
overloadable_binary_operator:
/*'+' | '-' | */ '*' | '/' | '%' | '&' | '|' | '^' | '<<' | '>' '>' | '==' | '!=' | '>' | '<' | '>=' | '<=' ;
conversion_operator_declaration:
conversion_operator_declarator operator_body ;
conversion_operator_declarator:
('implicit' | 'explicit') 'operator' type '(' type identifier ')' ;
// rewrite to a method
conversion_operator_declaration[CommonTree atts, CommonTree mods]
scope SymTab;
@init {
$SymTab::symtab = new Dictionary<string,TypeRepTemplate>();
}:
h=conversion_operator_declarator { $SymTab::symtab[$h.var] = $h.varTy; } b=operator_body meth=magicCastOperator[$mods, $h.tree, $b.tree] -> $meth;
conversion_operator_declarator returns [ String var, TypeRepTemplate varTy ] :
('implicit' | 'explicit') o='operator' t=type '(' f=type n=identifier ')' { $var = $n.thetext; $varTy = $f.dotNetType; } -> $o $t $f $n;
operator_body:
block ;
@ -1455,3 +1472,17 @@ magicScrutineeVar [IToken tok] returns [String thetext]
$thetext = "__dummyScrutVar" + dummyScrutVarCtr++;
}:
-> IDENTIFIER[tok,$thetext];
magicCastOperator[CommonTree mods, CommonTree header, CommonTree body]
@init {
IToken tok = ((CommonTree)$header.Children[0]).Token;
CommonTree toType = dupTree((CommonTree)$header.Children[1]);
CommonTree fromType = dupTree((CommonTree)$header.Children[2]);
CommonTree paramName = dupTree((CommonTree)$header.Children[3]);
}:
-> ^(METHOD[tok, "METHOD"]
{ dupTree($mods) }
{ toType } IDENTIFIER[tok, "__cast"] ^(PARAMS[tok, "PARAMS"] { fromType } { paramName})
{ dupTree(body) }
EXCEPTION[tok, "Throwable"])
;

View File

@ -1136,7 +1136,10 @@ conversion_operator_declaration:
conversion_operator_declarator operator_body ;
conversion_operator_declarator:
(i='implicit' { Warning($i.line, "[UNSUPPORTED] implicit user defined casts, an explicit cast is always required."); } | 'explicit') 'operator' tt=type '(' tf=type identifier ')'
{ ((ClassRepTemplate)$NSContext::currentTypeRep).Casts.Add(new CastRepTemplate($tf.thetext, $tt.thetext));
{
CastRepTemplate kast = new CastRepTemplate($tf.thetext, $tt.thetext);
kast.SurroundingTypeName = $NSContext::currentTypeRep.TypeName;
((ClassRepTemplate)$NSContext::currentTypeRep).Casts.Add(kast);
Debug("Processing conversion declaration");
}
;