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

rewrite since namespace aliases need to be kept separate from the search path

This commit is contained in:
Kevin Glynn 2011-01-08 17:15:48 +01:00
parent 6270613b46
commit 2f87602d6c
7 changed files with 255 additions and 138 deletions

View File

@ -95,30 +95,28 @@ namespace RusticiSoftware.Translator.CLR
#endregion #endregion
} }
// A use entry. An optional alias and a fully qualified namespace // A namespace alias entry.
public class UseRepTemplate : IEquatable<UseRepTemplate> public class AliasRepTemplate : IEquatable<AliasRepTemplate>
{ {
public string Alias { get; set; } public string Alias { get; set; }
public string Namespace { get; set; } public string Namespace { get; set; }
public UseRepTemplate () : this(null) public AliasRepTemplate ()
{ {
Alias = null;
Namespace = null;
} }
public UseRepTemplate (string u) : this(null, u) public AliasRepTemplate (string a, string u)
{
}
public UseRepTemplate (string a, string u)
{ {
Alias = a; Alias = a;
Namespace = u; Namespace = u;
} }
#region Equality #region Equality
public bool Equals (UseRepTemplate other) public bool Equals (AliasRepTemplate other)
{ {
if (other == null) if (other == null)
return false; return false;
@ -129,19 +127,19 @@ namespace RusticiSoftware.Translator.CLR
public override bool Equals (object obj) public override bool Equals (object obj)
{ {
UseRepTemplate temp = obj as UseRepTemplate; AliasRepTemplate temp = obj as AliasRepTemplate;
if (!Object.ReferenceEquals (temp, null)) if (!Object.ReferenceEquals (temp, null))
return this.Equals (temp); return this.Equals (temp);
return false; return false;
} }
public static bool operator == (UseRepTemplate a1, UseRepTemplate a2) public static bool operator == (AliasRepTemplate a1, AliasRepTemplate a2)
{ {
return Object.Equals (a1, a2); return Object.Equals (a1, a2);
} }
public static bool operator != (UseRepTemplate a1, UseRepTemplate a2) public static bool operator != (AliasRepTemplate a1, AliasRepTemplate a2)
{ {
return !(a1 == a2); return !(a1 == a2);
} }
@ -880,12 +878,17 @@ namespace RusticiSoftware.Translator.CLR
// Path to use when resolving types // Path to use when resolving types
[XmlArrayItem("Use")] [XmlArrayItem("Use")]
public UseRepTemplate[] Uses { get; set; } public string[] Uses { get; set; }
// Aliases for namespaces
[XmlArrayItem("Alias")]
public AliasRepTemplate[] Aliases { get; set; }
public TypeRepTemplate () : base() public TypeRepTemplate () : base()
{ {
TypeName = null; TypeName = null;
Uses = null; Uses = null;
Aliases = null;
} }
@ -894,11 +897,12 @@ namespace RusticiSoftware.Translator.CLR
TypeName = typeName; TypeName = typeName;
} }
protected TypeRepTemplate (string tName, string[] tParams, UseRepTemplate[] usePath, string[] imports, string javaTemplate) : base(imports, javaTemplate) protected TypeRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] imports, string javaTemplate) : base(imports, javaTemplate)
{ {
TypeName = tName; TypeName = tName;
TypeParams = tParams; TypeParams = tParams;
Uses = usePath; Uses = usePath;
Aliases = aliases;
} }
public override string mkJava() { public override string mkJava() {
@ -1003,6 +1007,14 @@ namespace RusticiSoftware.Translator.CLR
return false; return false;
} }
} }
if (Aliases != other.Aliases) {
if (Aliases == null || other.Aliases == null || Aliases.Length != other.Aliases.Length)
return false;
for (int i = 0; i < Aliases.Length; i++) {
if (Aliases[i] != other.Aliases[i])
return false;
}
}
if (TypeParams != other.TypeParams) { if (TypeParams != other.TypeParams) {
if (TypeParams == null || other.TypeParams == null || TypeParams.Length != other.TypeParams.Length) if (TypeParams == null || other.TypeParams == null || TypeParams.Length != other.TypeParams.Length)
return false; return false;
@ -1039,7 +1051,12 @@ namespace RusticiSoftware.Translator.CLR
{ {
int hashCode = base.GetHashCode (); int hashCode = base.GetHashCode ();
if (Uses != null) { if (Uses != null) {
foreach (UseRepTemplate e in Uses) { foreach (string e in Uses) {
hashCode ^= e.GetHashCode();
}
}
if (Aliases != null) {
foreach (AliasRepTemplate e in Aliases) {
hashCode ^= e.GetHashCode(); hashCode ^= e.GetHashCode();
} }
} }
@ -1298,8 +1315,8 @@ namespace RusticiSoftware.Translator.CLR
{ {
} }
protected InterfaceRepTemplate (string tName, string[] tParams, UseRepTemplate[] usePath, string[] inherits, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, string[] imps, string javaTemplate) protected InterfaceRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, string[] imps, string javaTemplate)
: base(tName, tParams, usePath, imps, javaTemplate) : base(tName, tParams, usePath, aliases, imps, javaTemplate)
{ {
Inherits = inherits; Inherits = inherits;
_methods = ms; _methods = ms;
@ -1483,17 +1500,17 @@ namespace RusticiSoftware.Translator.CLR
{ {
} }
public ClassRepTemplate (string tName, string[] tParams, UseRepTemplate[] usePath, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> cts, public ClassRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> cts,
string[] imports, string javaTemplate) string[] imports, string javaTemplate)
: base(tName, tParams, usePath, inherits, ms, ps, es, ixs, imports, javaTemplate) : base(tName, tParams, usePath, aliases, inherits, ms, ps, es, ixs, imports, javaTemplate)
{ {
_constructors = cs; _constructors = cs;
_fields = fs; _fields = fs;
_casts = cts; _casts = cts;
} }
public ClassRepTemplate (string tName, string[] tParams, UseRepTemplate[] usePath, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> cts) public ClassRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> cts)
: base(tName, tParams, usePath, inherits, ms, ps, es, ixs, null, null) : base(tName, tParams, usePath, aliases, inherits, ms, ps, es, ixs, null, null)
{ {
_constructors = cs; _constructors = cs;
_fields = fs; _fields = fs;
@ -1621,14 +1638,14 @@ namespace RusticiSoftware.Translator.CLR
{ {
} }
public StructRepTemplate (string tName, string[] tParams, UseRepTemplate[] usePath, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> cts, public StructRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> cts,
string[] imports, string javaTemplate) : base(tName, tParams, usePath, inherits, cs, ms, ps, fs, es, ixs, cts, string[] imports, string javaTemplate) : base(tName, tParams, usePath, aliases, inherits, cs, ms, ps, fs, es, ixs, cts,
imports, javaTemplate) imports, javaTemplate)
{ {
} }
public StructRepTemplate (string tName, string[] tParams, UseRepTemplate[] usePath, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> cts) public StructRepTemplate (string tName, string[] tParams, string[] usePath, AliasRepTemplate[] aliases, string[] inherits, List<ConstructorRepTemplate> cs, List<MethodRepTemplate> ms, List<PropRepTemplate> ps, List<FieldRepTemplate> fs, List<FieldRepTemplate> es, List<MethodRepTemplate> ixs, List<CastRepTemplate> cts)
: base(tName, tParams, usePath, inherits, cs, ms, ps, fs, es, ixs, cts, null, null) : base(tName, tParams, usePath, aliases, inherits, cs, ms, ps, fs, es, ixs, cts, null, null)
{ {
} }

View File

@ -305,10 +305,15 @@ namespace RusticiSoftware.Translator.CSharp
if (cfg.DebugLevel >= 10) if (cfg.DebugLevel >= 10)
{ {
Console.Out.WriteLine("Search Path:"); Console.Out.WriteLine("Namepace Search Path:");
for (int j = 0; j < javaMaker.CUMap[typeName].SearchPathKeys.Count; j++) foreach (String ns in javaMaker.CUMap[typeName].SearchPath)
{ {
Console.Out.WriteLine("{0} => {1}", javaMaker.CUMap[typeName].SearchPathKeys[j], javaMaker.CUMap[typeName].SearchPathValues[j]); Console.Out.WriteLine(ns);
}
Console.Out.WriteLine("Namepace Alias Map:");
for (int j = 0; j < javaMaker.CUMap[typeName].NameSpaceAliasKeys.Count; j++)
{
Console.Out.WriteLine("{0} => {1}", javaMaker.CUMap[typeName].NameSpaceAliasKeys[j], javaMaker.CUMap[typeName].NameSpaceAliasValues[j]);
} }
} }
@ -358,8 +363,9 @@ namespace RusticiSoftware.Translator.CSharp
netMaker.Cfg = cfg; netMaker.Cfg = cfg;
netMaker.AppEnv = AppEnv; netMaker.AppEnv = AppEnv;
netMaker.SearchPathKeys = javaMaker.CUMap[typeName].SearchPathKeys; netMaker.SearchPath = javaMaker.CUMap[typeName].SearchPath;
netMaker.SearchPathValues = javaMaker.CUMap[typeName].SearchPathValues; netMaker.AliasKeys = javaMaker.CUMap[typeName].NameSpaceAliasKeys;
netMaker.AliasNamespaces = javaMaker.CUMap[typeName].NameSpaceAliasValues;
if (cfg.DebugLevel > 5) Console.Out.WriteLine("Translating {0} Net Calls to Java", javaFName); if (cfg.DebugLevel > 5) Console.Out.WriteLine("Translating {0} Net Calls to Java", javaFName);
NetMaker.compilation_unit_return javaCompilationUnit = netMaker.compilation_unit(); NetMaker.compilation_unit_return javaCompilationUnit = netMaker.compilation_unit();

View File

@ -100,14 +100,20 @@ namespace RusticiSoftware.Translator.CSharp
// Wraps a compilation unit with its imports search path // Wraps a compilation unit with its imports search path
public class CUnit { public class CUnit {
public CUnit(CommonTree inTree, List<string> inSearchKeys, List<string> inSearchValues) { public CUnit(CommonTree inTree, List<string> inSearchPath, List<string> inAliasKeys, List<string> inAliasValues) {
Tree = inTree; Tree = inTree;
SearchPathKeys = inSearchKeys; SearchPath = inSearchPath;
SearchPathValues = inSearchValues; NameSpaceAliasKeys = inAliasKeys;
NameSpaceAliasValues = inAliasValues;
} }
public CommonTree Tree {get; set;} public CommonTree Tree {get; set;}
public List<string> SearchPathKeys {get; set;}
public List<string> SearchPathValues {get; set;} // namespaces in scope
public List<string> SearchPath {get; set;}
// aliases for namespaces
public List<string> NameSpaceAliasKeys {get; set;}
public List<string> NameSpaceAliasValues {get; set;}
} }
} }

View File

@ -20,11 +20,13 @@ scope NSContext {
int filler; int filler;
string currentNS; string currentNS;
// all namespaces in scope, these two lists are actually a map from alias to namespace // namespaces in scope
// so aliases[i] -> namespaces[i]
// for namespaces without an alias we just map them to themselves
List<string> aliases;
List<string> namespaces; List<string> namespaces;
// Alias map: these two lists are actually a map from alias to namespace
// so aliases[i] -> namespaces[i]
List<string> aliasKeys;
List<string> aliasNamespaces;
} }
// A scope to keep track of the current type context // A scope to keep track of the current type context
@ -55,12 +57,12 @@ scope TypeContext {
} }
} }
protected List<string> CollectAliases { protected List<string> CollectSearchPath {
get { get {
List<string> ret = new List<string>(); List<string> ret = new List<string>();
Object[] nsCtxtArr = $NSContext.ToArray(); Object[] nsCtxtArr = $NSContext.ToArray();
for (int i = nsCtxtArr.Length - 1; i >= 0; i--) { for (int i = nsCtxtArr.Length - 1; i >= 0; i--) {
foreach (string v in ((NSContext_scope)nsCtxtArr[i]).aliases) { foreach (string v in ((NSContext_scope)nsCtxtArr[i]).namespaces) {
ret.Add(v); ret.Add(v);
} }
} }
@ -68,12 +70,25 @@ scope TypeContext {
} }
} }
protected List<string> CollectNamespaces { protected List<string> CollectAliasKeys {
get { get {
List<string> ret = new List<string>(); List<string> ret = new List<string>();
Object[] nsCtxtArr = $NSContext.ToArray(); Object[] nsCtxtArr = $NSContext.ToArray();
for (int i = nsCtxtArr.Length - 1; i >= 0; i--) { for (int i = nsCtxtArr.Length - 1; i >= 0; i--) {
foreach (string v in ((NSContext_scope)nsCtxtArr[i]).namespaces) { foreach (string v in ((NSContext_scope)nsCtxtArr[i]).aliasKeys) {
ret.Add(v);
}
}
return ret;
}
}
protected List<string> CollectAliasNamespaces {
get {
List<string> ret = new List<string>();
Object[] nsCtxtArr = $NSContext.ToArray();
for (int i = nsCtxtArr.Length - 1; i >= 0; i--) {
foreach (string v in ((NSContext_scope)nsCtxtArr[i]).aliasNamespaces) {
ret.Add(v); ret.Add(v);
} }
} }
@ -236,8 +251,9 @@ compilation_unit
scope NSContext; scope NSContext;
@init { @init {
$NSContext::currentNS = ""; $NSContext::currentNS = "";
$NSContext::aliases = new List<string>();
$NSContext::namespaces = new List<string>(); $NSContext::namespaces = new List<string>();
$NSContext::aliasKeys = new List<string>();
$NSContext::aliasNamespaces = new List<string>();
} }
: :
namespace_body; namespace_body;
@ -246,14 +262,14 @@ namespace_declaration
scope NSContext; scope NSContext;
@init { @init {
$NSContext::currentNS = ""; $NSContext::currentNS = "";
$NSContext::aliases = new List<string>();
$NSContext::namespaces = new List<string>(); $NSContext::namespaces = new List<string>();
$NSContext::aliasKeys = new List<string>();
$NSContext::aliasNamespaces = new List<string>();
}: }:
'namespace' qi=qualified_identifier 'namespace' qi=qualified_identifier
{ {
// extend parent namespace // extend parent namespace
$NSContext::currentNS = this.ParentNameSpace + $qi.thetext; $NSContext::currentNS = this.ParentNameSpace + $qi.thetext;
$NSContext::aliases.Add($NSContext::currentNS);
$NSContext::namespaces.Add($NSContext::currentNS); $NSContext::namespaces.Add($NSContext::currentNS);
} }
namespace_block ';'? ; namespace_block ';'? ;
@ -271,9 +287,10 @@ using_directive:
(using_alias_directive (using_alias_directive
| using_namespace_directive) ; | using_namespace_directive) ;
using_alias_directive: using_alias_directive:
'using' identifier '=' namespace_or_type_name ';' {$NSContext::aliases.Add($identifier.text);$NSContext::namespaces.Add($namespace_or_type_name.thetext); } ; 'using' identifier '=' namespace_or_type_name ';'
{$NSContext::aliasKeys.Add($identifier.text);$NSContext::aliasNamespaces.Add($namespace_or_type_name.thetext); } ;
using_namespace_directive: using_namespace_directive:
'using' namespace_name ';' {$NSContext::aliases.Add($namespace_name.thetext);$NSContext::namespaces.Add($namespace_name.thetext); }; 'using' namespace_name ';' {$NSContext::namespaces.Add($namespace_name.thetext); };
namespace_member_declarations: namespace_member_declarations:
namespace_member_declaration+ ; namespace_member_declaration+ ;
namespace_member_declaration namespace_member_declaration
@ -282,7 +299,7 @@ namespace_member_declaration
} }
@after { @after {
if (isCompUnit) { if (isCompUnit) {
CUMap.Add(ns+"."+$ty.name, new CUnit($namespace_member_declaration.tree,CollectAliases,CollectNamespaces)); CUMap.Add(ns+"."+$ty.name, new CUnit($namespace_member_declaration.tree,CollectSearchPath,CollectAliasKeys,CollectAliasNamespaces));
CUKeys.Add(ns+"."+$ty.name); CUKeys.Add(ns+"."+$ty.name);
}; };
} }

View File

@ -13,11 +13,15 @@ scope NSContext {
string currentNS; string currentNS;
// all namespaces in scope, these two lists are actually a map from alias to namespace // all namespaces in scope
// so aliases[i] -> namespaces[i]
// for namespaces without an alias we just map them to themselves
List<string> aliases;
List<string> namespaces; List<string> namespaces;
// all namespaces in all scopes
List<string> globalNamespaces;
}
// A scope to keep track of the mapping from variables to types
scope SymTab {
Dictionary<string,TypeRepTemplate> symtab;
} }
@namespace { RusticiSoftware.Translator.CSharp } @namespace { RusticiSoftware.Translator.CSharp }
@ -31,8 +35,9 @@ scope NSContext {
@members @members
{ {
// Initial namespace search path gathered in JavaMaker // Initial namespace search path gathered in JavaMaker
public List<string> SearchPathKeys { get; set; } public List<string> SearchPath { get; set; }
public List<string> SearchPathValues { get; set; } public List<string> AliasKeys { get; set; }
public List<string> AliasNamespaces { get; set; }
private Set<string> Imports { get; set; } private Set<string> Imports { get; set; }
@ -59,27 +64,19 @@ scope NSContext {
} }
protected TypeRepTemplate findType(string name) { protected TypeRepTemplate findType(string name) {
TypeRepTemplate ret = null; return AppEnv.Search($NSContext::globalNamespaces, name);
object[] ctxts = $NSContext.ToArray();
foreach (NSContext_scope ctxt in ctxts) {
for (int i = ctxt.namespaces.Count - 1; i >= 0; i--) {
String ns = ctxt.namespaces[i];
String fullName = (ns ?? "") + (String.IsNullOrEmpty(ns) ? "" : ".") + name;
if (AppEnv.ContainsKey(fullName)) {
ret = AppEnv[fullName];
break;
}
}
}
// Check if name is fully qualified
if (ret == null && AppEnv.ContainsKey(name)) {
ret = AppEnv[name];
}
// if (ret != null)
// Console.Out.WriteLine("findType: found {0}", ret.TypeName);
return ret;
} }
private TypeRepTemplate objectType = null;
protected TypeRepTemplate ObjectType {
get {
if (objectType == null) {
objectType = findType("System.Object");
}
return objectType;
}
}
} }
compilation_unit compilation_unit
@ -89,8 +86,8 @@ scope NSContext;
Imports = new Set<string>(); Imports = new Set<string>();
// TODO: Do we need to ensure we have access to System? If so, can add it here. // TODO: Do we need to ensure we have access to System? If so, can add it here.
$NSContext::aliases = SearchPathKeys; $NSContext::namespaces = SearchPath ?? new List<string>();
$NSContext::namespaces = SearchPathValues; $NSContext::globalNamespaces = SearchPath ?? new List<string>();
}: }:
^(pkg=PACKAGE ns=PAYLOAD { $NSContext::currentNS = $ns.text; } m=modifiers? dec=type_declaration ) ^(pkg=PACKAGE ns=PAYLOAD { $NSContext::currentNS = $ns.text; } m=modifiers? dec=type_declaration )
-> ^($pkg $ns { mkImports() } $m? $dec); -> ^($pkg $ns { mkImports() } $m? $dec);
@ -119,7 +116,7 @@ class_member_declaration:
| ^(INTERFACE attributes? modifiers? interface_declaration) | ^(INTERFACE attributes? modifiers? interface_declaration)
| ^(CLASS attributes? modifiers? class_declaration) | ^(CLASS attributes? modifiers? class_declaration)
| ^(INDEXER attributes? modifiers? type type_name? indexer_declaration) | ^(INDEXER attributes? modifiers? type type_name? indexer_declaration)
| ^(FIELD attributes? modifiers? type field_declaration) | ^(FIELD attributes? modifiers? type field_declaration[$type.dotNetType])
| ^(OPERATOR attributes? modifiers? type operator_declaration) | ^(OPERATOR attributes? modifiers? type operator_declaration)
| ^(ENUM attributes? modifiers? enum_declaration) | ^(ENUM attributes? modifiers? enum_declaration)
| ^(DELEGATE attributes? modifiers? delegate_declaration) | ^(DELEGATE attributes? modifiers? delegate_declaration)
@ -390,7 +387,9 @@ pointer_type returns [TypeRepTemplate dotNetType]:
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
// Statement Section // Statement Section
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
block: block
scope SymTab;
:
';' ';'
| '{' statement_list? '}'; | '{' statement_list? '}';
statement_list: statement_list:
@ -399,7 +398,7 @@ statement_list:
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
// Expression Section // Expression Section
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
expression: expression returns [TypeRepTemplate dotNetType]:
(unary_expression assignment_operator) => assignment (unary_expression assignment_operator) => assignment
| non_assignment_expression | non_assignment_expression
; ;
@ -407,21 +406,21 @@ expression_list:
expression (',' expression)* ; expression (',' expression)* ;
assignment: assignment:
unary_expression assignment_operator expression ; unary_expression assignment_operator expression ;
unary_expression: unary_expression returns [TypeRepTemplate dotNetType]:
//('(' arguments ')' ('[' | '.' | '(')) => primary_or_array_creation_expression //('(' arguments ')' ('[' | '.' | '(')) => primary_or_array_creation_expression
//(cast_expression) => cast_expression //(cast_expression) => cast_expression
^(CAST_EXPR type unary_expression) ^(CAST_EXPR type unary_expression) { $dotNetType = $type.dotNetType; }
| primary_or_array_creation_expression | primary_or_array_creation_expression
| ^(MONOPLUS unary_expression) | ^(MONOPLUS u1=unary_expression) { $dotNetType = $u1.dotNetType; }
| ^(MONOMINUS unary_expression) | ^(MONOMINUS u2=unary_expression) { $dotNetType = $u2.dotNetType; }
| ^(MONONOT unary_expression) | ^(MONONOT u3=unary_expression) { $dotNetType = $u3.dotNetType; }
| ^(MONOTWIDDLE unary_expression) | ^(MONOTWIDDLE u4=unary_expression) { $dotNetType = $u4.dotNetType; }
| ^(PREINC unary_expression) | ^(PREINC u5=unary_expression) { $dotNetType = $u5.dotNetType; }
| ^(PREDEC unary_expression) | ^(PREDEC u6=unary_expression) { $dotNetType = $u6.dotNetType; }
| ^(MONOSTAR unary_expression) | ^(MONOSTAR unary_expression) { $dotNetType = ObjectType; }
| ^(ADDRESSOF unary_expression) | ^(ADDRESSOF unary_expression) { $dotNetType = ObjectType; }
| ^(PARENS expression) | ^(PARENS expression) { $dotNetType = $expression.dotNetType; }
; ;
//cast_expression: //cast_expression:
// '(' type ')' non_assignment_expression ; // '(' type ')' non_assignment_expression ;
@ -613,17 +612,20 @@ attribute_argument_expression:
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
class_declaration class_declaration
scope NSContext; scope NSContext,SymTab;
@init { @init {
$NSContext::aliases = new List<string>();
$NSContext::namespaces = new List<string>(); $NSContext::namespaces = new List<string>();
$NSContext::globalNamespaces = new List<string>(((NSContext_scope)$NSContext.ToArray()[1]).globalNamespaces);
$SymTab::symtab = new Dictionary<string, TypeRepTemplate>();
} }
: :
^(CLASS identifier { $NSContext::currentNS = ParentNameSpace + "." + $identifier.thetext; } type_parameter_constraints_clauses? type_parameter_list? ^(CLASS identifier { $NSContext::currentNS = ParentNameSpace + "." + $identifier.thetext; } type_parameter_constraints_clauses? type_parameter_list?
class_implements? class_implements?
{ {
$NSContext::aliases.Add($NSContext::currentNS); $NSContext::namespaces.Add($NSContext::currentNS);
$NSContext::namespaces.Add($NSContext::currentNS); $NSContext::globalNamespaces.Add($NSContext::currentNS);
// TODO: base to map to parent type
$SymTab::symtab["this"] = AppEnv.Search($NSContext::currentNS);
} }
class_body ) ; class_body ) ;
@ -668,15 +670,17 @@ constant_expression:
expression; expression;
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
field_declaration: field_declaration[TypeRepTemplate fieldType]:
variable_declarators ; variable_declarators[$fieldType] ;
variable_declarators: variable_declarators[TypeRepTemplate varType]:
variable_declarator (',' variable_declarator)* ; variable_declarator[varType] (',' variable_declarator[varType])* ;
variable_declarator: variable_declarator[TypeRepTemplate varType]:
type_name ('=' variable_initializer)? ; // eg. event EventHandler IInterface.VariableName = Foo; type_name ('=' variable_initializer)? ; // eg. event EventHandler IInterface.VariableName = Foo;
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
method_declaration: method_declaration
scope SymTab;
:
method_header method_body ; method_header method_body ;
method_header: method_header:
^(METHOD_HEADER attributes? modifiers? type member_name type_parameter_constraints_clauses? type_parameter_list? formal_parameter_list?); ^(METHOD_HEADER attributes? modifiers? type member_name type_parameter_constraints_clauses? type_parameter_list? formal_parameter_list?);
@ -708,7 +712,7 @@ accessor_body:
event_declaration: event_declaration:
'event' type 'event' type
((member_name '{') => member_name '{' event_accessor_declarations '}' ((member_name '{') => member_name '{' event_accessor_declarations '}'
| variable_declarators ';') // typename=foo; | variable_declarators[$type.dotNetType] ';') // typename=foo;
; ;
event_modifiers: event_modifiers:
modifier+ ; modifier+ ;
@ -862,7 +866,7 @@ statement_plus:
| embedded_statement | embedded_statement
; ;
embedded_statement: embedded_statement:
block block
| ^(IF boolean_expression SEP embedded_statement else_statement?) | ^(IF boolean_expression SEP embedded_statement else_statement?)
| ^('switch' expression switch_section*) | ^('switch' expression switch_section*)
| iteration_statement // while, do, for, foreach | iteration_statement // while, do, for, foreach
@ -978,7 +982,7 @@ predefined_type returns [TypeRepTemplate dotNetType]
string ns = ""; string ns = "";
} }
@after { @after {
$dotNetType = AppEnv[ns]; $dotNetType = AppEnv.Search(ns);
}: }:
'bool' { ns = "System.Boolean"; } 'bool' { ns = "System.Boolean"; }
| 'byte' { ns = "System.Byte"; } | 'byte' { ns = "System.Byte"; }
@ -1011,16 +1015,22 @@ also_keyword:
| 'equals' | 'select' | 'pragma' | 'let' | 'remove' | 'get' | 'set' | 'var' | '__arglist' | 'dynamic' | 'elif' | 'equals' | 'select' | 'pragma' | 'let' | 'remove' | 'get' | 'set' | 'var' | '__arglist' | 'dynamic' | 'elif'
| 'endif' | 'define' | 'undef'; | 'endif' | 'define' | 'undef';
literal: literal returns [TypeRepTemplate dotNetType]
Real_literal @init {
| NUMBER string ns = "System.Object";
| LONGNUMBER }
@after {
$dotNetType = AppEnv.Search(ns);
}:
Real_literal
| NUMBER { ns = "System.Int32"; }
| LONGNUMBER { ns = "System.Int64"; }
| Hex_number | Hex_number
| Character_literal | Character_literal { ns = "System.Char"; }
| STRINGLITERAL | STRINGLITERAL { ns = "System.String"; }
| Verbatim_string_literal | Verbatim_string_literal { ns = "System.String"; }
| TRUE | TRUE { ns = "System.Bool"; }
| FALSE | FALSE { ns = "System.Bool"; }
| NULL | NULL { ns = "System.Object"; }
; ;

View File

@ -17,7 +17,8 @@ options {
// A scope to keep track of the namespaces available at any point in the program // A scope to keep track of the namespaces available at any point in the program
scope NSContext { scope NSContext {
IList<UseRepTemplate> nss; IList<string> searchpath;
IList<AliasRepTemplate> aliases;
string currentNS; string currentNS;
TypeRepTemplate currentTypeRep; TypeRepTemplate currentTypeRep;
} }
@ -34,20 +35,41 @@ scope NSContext {
@members @members
{ {
protected UseRepTemplate[] NameSpaceContext { protected string[] CollectUses {
get { get {
// We return the elements in source order (hopefully less confusing) // We return the elements in source order (hopefully less confusing)
// so when looking for types we search from last element to first. // so when looking for types we search from last element to first.
// here we are getting scopes in the opposite order so we need some // here we are getting scopes in the opposite order so we need some
// jiggery pokery to restore desired order. // jiggery pokery to restore desired order.
List<UseRepTemplate> rets = new List<UseRepTemplate>(); List<string> rets = new List<string>();
// returns in LIFO order, like you would expect from a stack // returns in LIFO order, like you would expect from a stack
// sigh, in C# we can't index into the scopes like you can in Java // sigh, in C# we can't index into the scopes like you can in Java
// so we resort to a bit of low level hackery to get the ns lists // so we resort to a bit of low level hackery to get the ns lists
foreach (NSContext_scope nscontext in $NSContext) { foreach (NSContext_scope nscontext in $NSContext) {
IList<UseRepTemplate> nss = nscontext.nss; IList<string> uses = nscontext.searchpath;
for (int i = nss.Count - 1; i >= 0; i--) { for (int i = uses.Count - 1; i >= 0; i--) {
rets.Add(nss[i]); rets.Add(uses[i]);
}
}
// And now return reversed list
rets.Reverse();
return rets.ToArray();
}
}
protected AliasRepTemplate[] CollectAliases {
get {
// We return the elements in source order (hopefully less confusing)
// so when looking for types we search from last element to first.
// here we are getting scopes in the opposite order so we need some
// jiggery pokery to restore desired order.
List<AliasRepTemplate> rets = new List<AliasRepTemplate>();
// returns in LIFO order, like you would expect from a stack
// sigh, in C# we can't index into the scopes like you can in Java
// so we resort to a bit of low level hackery to get the ns lists
foreach (NSContext_scope nscontext in $NSContext) {
IList<AliasRepTemplate> aliases = nscontext.aliases;
for (int i = aliases.Count - 1; i >= 0; i--) {
rets.Add(aliases[i]);
} }
} }
// And now return reversed list // And now return reversed list
@ -74,7 +96,8 @@ compilation_unit
scope NSContext; scope NSContext;
@init{ @init{
// For initial, file level scope // For initial, file level scope
$NSContext::nss = new List<UseRepTemplate>(); $NSContext::searchpath = new List<string>();
$NSContext::aliases = new List<AliasRepTemplate>();
$NSContext::currentNS = ""; $NSContext::currentNS = "";
$NSContext::currentTypeRep = null; $NSContext::currentTypeRep = null;
} }
@ -87,13 +110,14 @@ scope NSContext;
namespace_declaration namespace_declaration
scope NSContext; scope NSContext;
@init{ @init{
$NSContext::nss = new List<UseRepTemplate>(); $NSContext::searchpath = new List<string>();
$NSContext::aliases = new List<AliasRepTemplate>();
$NSContext::currentTypeRep = null; $NSContext::currentTypeRep = null;
} }
: :
'namespace' qi=qualified_identifier 'namespace' qi=qualified_identifier
{ Debug("namespace: " + $qi.thetext); { Debug("namespace: " + $qi.thetext);
$NSContext::nss.Add(new UseRepTemplate($qi.thetext)); $NSContext::searchpath.Add($qi.thetext);
// extend parent namespace // extend parent namespace
$NSContext::currentNS = ParentNameSpace + (String.IsNullOrEmpty(ParentNameSpace) ? "" : ".") + $qi.thetext; $NSContext::currentNS = ParentNameSpace + (String.IsNullOrEmpty(ParentNameSpace) ? "" : ".") + $qi.thetext;
} }
@ -112,11 +136,11 @@ using_directive:
(using_alias_directive (using_alias_directive
| using_namespace_directive) ; | using_namespace_directive) ;
using_alias_directive using_alias_directive
@after{ $NSContext::nss.Add(new UseRepTemplate($i.thetext, $ns.thetext));} @after{ $NSContext::aliases.Add(new AliasRepTemplate($i.thetext, $ns.thetext));}
: :
'using' i=identifier '=' ns=namespace_or_type_name ';' ; 'using' i=identifier '=' ns=namespace_or_type_name ';' ;
using_namespace_directive using_namespace_directive
@after{ $NSContext::nss.Add(new UseRepTemplate($ns.thetext)); } @after{ $NSContext::searchpath.Add($ns.thetext); }
: :
'using' ns=namespace_name ';' ; 'using' ns=namespace_name ';' ;
namespace_member_declarations: namespace_member_declarations:
@ -641,20 +665,22 @@ attribute_argument_expression:
class_declaration class_declaration
scope NSContext; scope NSContext;
@init { @init {
$NSContext::nss = new List<UseRepTemplate>(); $NSContext::searchpath = new List<string>();
$NSContext::aliases = new List<AliasRepTemplate>();
ClassRepTemplate klass = new ClassRepTemplate(); ClassRepTemplate klass = new ClassRepTemplate();
} }
: :
'class' type_or_generic 'class' type_or_generic
{ {
Debug("Processing class: " + $type_or_generic.type); Debug("Processing class: " + $type_or_generic.type);
klass.Uses = this.NameSpaceContext; klass.Uses = this.CollectUses;
klass.Aliases = this.CollectAliases;
klass.TypeName = this.ParentNameSpace + "." + mkTypeName($type_or_generic.type, $type_or_generic.generic_arguments); klass.TypeName = this.ParentNameSpace + "." + mkTypeName($type_or_generic.type, $type_or_generic.generic_arguments);
if ($type_or_generic.generic_arguments.Count > 0) { if ($type_or_generic.generic_arguments.Count > 0) {
klass.TypeParams = $type_or_generic.generic_arguments.ToArray(); klass.TypeParams = $type_or_generic.generic_arguments.ToArray();
} }
// Nested types can see things in this space // Nested types can see things in this space
$NSContext::nss.Add(new UseRepTemplate(klass.TypeName)); $NSContext::searchpath.Add(klass.TypeName);
$NSContext::currentNS = klass.TypeName; $NSContext::currentNS = klass.TypeName;
$NSContext::currentTypeRep = klass; $NSContext::currentTypeRep = klass;
AppEnv[klass.TypeName] = klass; AppEnv[klass.TypeName] = klass;
@ -776,17 +802,19 @@ remove_accessor_declaration:
enum_declaration enum_declaration
scope NSContext; scope NSContext;
@init { @init {
$NSContext::nss = new List<UseRepTemplate>(); $NSContext::searchpath = new List<string>();
$NSContext::aliases = new List<AliasRepTemplate>();
EnumRepTemplate eenum = new EnumRepTemplate(); EnumRepTemplate eenum = new EnumRepTemplate();
} }
: :
'enum' identifier enum_base? 'enum' identifier enum_base?
{ {
Debug("Processing enum: " + $identifier.text); Debug("Processing enum: " + $identifier.text);
eenum.Uses = this.NameSpaceContext; eenum.Uses = this.CollectUses;
eenum.Aliases = this.CollectAliases;
eenum.TypeName = this.ParentNameSpace + "." + $identifier.text; eenum.TypeName = this.ParentNameSpace + "." + $identifier.text;
// Nested types can see things in this space // Nested types can see things in this space
$NSContext::nss.Add(new UseRepTemplate(eenum.TypeName)); $NSContext::searchpath.Add(eenum.TypeName);
$NSContext::currentNS = eenum.TypeName; $NSContext::currentNS = eenum.TypeName;
$NSContext::currentTypeRep = eenum; $NSContext::currentTypeRep = eenum;
AppEnv[eenum.TypeName] = eenum; AppEnv[eenum.TypeName] = eenum;
@ -814,7 +842,8 @@ integral_type:
delegate_declaration delegate_declaration
scope NSContext; scope NSContext;
@init { @init {
$NSContext::nss = new List<UseRepTemplate>(); $NSContext::searchpath = new List<string>();
$NSContext::aliases = new List<AliasRepTemplate>();
DelegateRepTemplate dlegate = new DelegateRepTemplate(); DelegateRepTemplate dlegate = new DelegateRepTemplate();
} }
: :
@ -822,7 +851,8 @@ scope NSContext;
'(' formal_parameter_list? ')' type_parameter_constraints_clauses? ';' '(' formal_parameter_list? ')' type_parameter_constraints_clauses? ';'
{ {
Debug("Processing delegate: " + $identifier.text); Debug("Processing delegate: " + $identifier.text);
dlegate.Uses = this.NameSpaceContext; dlegate.Uses = this.CollectUses;
dlegate.Aliases = this.CollectAliases;
dlegate.TypeName = this.ParentNameSpace + "." + mkTypeName($identifier.text, $variant_generic_parameter_list.tyargs); dlegate.TypeName = this.ParentNameSpace + "." + mkTypeName($identifier.text, $variant_generic_parameter_list.tyargs);
if ($variant_generic_parameter_list.tyargs != null && $variant_generic_parameter_list.tyargs.Count > 0) { if ($variant_generic_parameter_list.tyargs != null && $variant_generic_parameter_list.tyargs.Count > 0) {
dlegate.TypeParams = $variant_generic_parameter_list.tyargs.ToArray(); dlegate.TypeParams = $variant_generic_parameter_list.tyargs.ToArray();
@ -903,20 +933,22 @@ parameter_array returns [ParamRepTemplate param]:
interface_declaration interface_declaration
scope NSContext; scope NSContext;
@init { @init {
$NSContext::nss = new List<UseRepTemplate>(); $NSContext::searchpath = new List<string>();
$NSContext::aliases = new List<AliasRepTemplate>();
InterfaceRepTemplate iface = new InterfaceRepTemplate(); InterfaceRepTemplate iface = new InterfaceRepTemplate();
} }
: :
'interface' identifier variant_generic_parameter_list? 'interface' identifier variant_generic_parameter_list?
{ {
Debug("Processing interface: " + $identifier.text); Debug("Processing interface: " + $identifier.text);
iface.Uses = this.NameSpaceContext; iface.Uses = this.CollectUses;
iface.Aliases = this.CollectAliases;
iface.TypeName = this.ParentNameSpace + "." + mkTypeName($identifier.text, $variant_generic_parameter_list.tyargs); iface.TypeName = this.ParentNameSpace + "." + mkTypeName($identifier.text, $variant_generic_parameter_list.tyargs);
if ($variant_generic_parameter_list.tyargs != null && $variant_generic_parameter_list.tyargs.Count > 0) { if ($variant_generic_parameter_list.tyargs != null && $variant_generic_parameter_list.tyargs.Count > 0) {
iface.TypeParams = $variant_generic_parameter_list.tyargs.ToArray(); iface.TypeParams = $variant_generic_parameter_list.tyargs.ToArray();
} }
// Nested types can see things in this space // Nested types can see things in this space
$NSContext::nss.Add(new UseRepTemplate(iface.TypeName)); $NSContext::searchpath.Add(iface.TypeName);
$NSContext::currentNS = iface.TypeName; $NSContext::currentNS = iface.TypeName;
$NSContext::currentTypeRep = iface; $NSContext::currentTypeRep = iface;
AppEnv[iface.TypeName] = iface; AppEnv[iface.TypeName] = iface;
@ -987,20 +1019,22 @@ method_modifiers:
struct_declaration struct_declaration
scope NSContext; scope NSContext;
@init { @init {
$NSContext::nss = new List<UseRepTemplate>(); $NSContext::searchpath = new List<string>();
$NSContext::aliases = new List<AliasRepTemplate>();
StructRepTemplate strukt = new StructRepTemplate(); StructRepTemplate strukt = new StructRepTemplate();
} }
: :
'struct' type_or_generic 'struct' type_or_generic
{ {
Debug("Processing struct: " + $type_or_generic.type); Debug("Processing struct: " + $type_or_generic.type);
strukt.Uses = this.NameSpaceContext; strukt.Uses = this.CollectUses;
strukt.Aliases = this.CollectAliases;
strukt.TypeName = this.ParentNameSpace + "." + mkTypeName($type_or_generic.type, $type_or_generic.generic_arguments); strukt.TypeName = this.ParentNameSpace + "." + mkTypeName($type_or_generic.type, $type_or_generic.generic_arguments);
if ($type_or_generic.generic_arguments.Count > 0) { if ($type_or_generic.generic_arguments.Count > 0) {
strukt.TypeParams = $type_or_generic.generic_arguments.ToArray(); strukt.TypeParams = $type_or_generic.generic_arguments.ToArray();
} }
// Nested types can see things in this space // Nested types can see things in this space
$NSContext::nss.Add(new UseRepTemplate(strukt.TypeName)); $NSContext::searchpath.Add(strukt.TypeName);
$NSContext::currentNS = strukt.TypeName; $NSContext::currentNS = strukt.TypeName;
$NSContext::currentTypeRep = strukt; $NSContext::currentTypeRep = strukt;
AppEnv[strukt.TypeName] = strukt; AppEnv[strukt.TypeName] = strukt;

View File

@ -171,6 +171,33 @@ namespace RusticiSoftware.Translator.Utils
} }
} }
// search for name, given searchPath
// searchPath is searched in reverse order
public TValue Search(List<string> searchPath, string name) {
TValue ret = default(TValue);
bool found = false;
for (int i = searchPath.Count-1; i >= 0; i--) {
String ns = searchPath[i];
String fullName = (ns ?? "") + (String.IsNullOrEmpty(ns) ? "" : ".") + name;
if (this.ContainsKey(fullName)) {
ret = this[fullName];
found = true;
break;
}
}
// Check if name is fully qualified
if (!found && this.ContainsKey(name)) {
ret = this[name];
}
// if (ret != null)
// Console.Out.WriteLine("findType: found {0}", ret.TypeName);
return ret;
}
public TValue Search(string name) {
return Search(new List<string>(), name);
}
public void Add(KeyValuePair<string, TValue> item) public void Add(KeyValuePair<string, TValue> item)
{ {
this.Add(item.Key, item.Value); this.Add(item.Key, item.Value);