├── .gitignore
├── AST
├── CAccess.cs
├── CArgument.cs
├── CArgumentList.cs
├── CArrayClass.cs
├── CAsst.cs
├── CAttribute.cs
├── CAttributeList.cs
├── CBaseAccess.cs
├── CBinaryOperator.cs
├── CCase.cs
├── CCast.cs
├── CCatch.cs
├── CClass.cs
├── CClassConst.cs
├── CComment.cs
├── CComparison.cs
├── CConcat.cs
├── CConst.cs
├── CConstantExpression.cs
├── CDefaultAccess.cs
├── CDictionaryType.cs
├── CDim.cs
├── CDirective.cs
├── CDo.cs
├── CEnum.cs
├── CExit.cs
├── CExpression.cs
├── CExpressionStatement.cs
├── CField.cs
├── CFile.cs
├── CFinally.cs
├── CFor.cs
├── CForEach.cs
├── CFunction.cs
├── CFunctionType.cs
├── CGlobalAccess.cs
├── CHtml.cs
├── CIf.cs
├── CIgnore.cs
├── CInterface.cs
├── CLambdaExpression.cs
├── CLambdaFunction.cs
├── CLock.cs
├── CLogic.cs
├── CMath.cs
├── CMathUnary.cs
├── CMember.cs
├── CMemberAccess.cs
├── CMemberOverload.cs
├── CMemberVariable.cs
├── CMethod.cs
├── CNew.cs
├── CNewline.cs
├── CNode.cs
├── CNot.cs
├── COnError.cs
├── COnExit.cs
├── COption.cs
├── COptionalByRef.cs
├── CParameters.cs
├── CParenExpression.cs
├── CPictureOfExpression.cs
├── CProgram.cs
├── CProperty.cs
├── CReDim.cs
├── CReturn.cs
├── CScope.cs
├── CSelect.cs
├── CSpecialEqual.cs
├── CStatement.cs
├── CStatementBlock.cs
├── CTernary.cs
├── CThisAccess.cs
├── CThrow.cs
├── CToken.cs
├── CTry.cs
├── CTypeRef.cs
├── CUnaryOperator.cs
├── CUnionClass.cs
├── CVariable.cs
├── CVariableBase.cs
├── CWhile.cs
├── CWith.cs
├── CWithAccess.cs
├── IAttributed.cs
├── IHasVisibility.cs
├── IVariable.cs
├── IVisitor.cs
└── TokenTypes.cs
├── App.config
├── BuiltIns.cs
├── ClrImporter.cs
├── CodeGenVisitor.cs
├── CompileException.cs
├── Compiler.cs
├── Example
├── App.config
├── Example.csproj
├── Program.cs
└── Properties
│ └── AssemblyInfo.cs
├── ICodeGenVisitor.cs
├── LICENSE
├── Program.cs
├── Properties
└── AssemblyInfo.cs
├── README.md
├── RoslynExtensions.cs
├── RoslynGenerator.cs
├── WasabiRoslynGenerator.csproj
├── WasabiRoslynGenerator.sln
├── packages.config
└── was_out
└── .gitignore
/.gitignore:
--------------------------------------------------------------------------------
1 | *.suo
2 | *.user
3 | *.userprefs
4 | [Bb]in/
5 | [Oo]bj/
6 | x64/
7 | x86/
8 |
9 | # NuGet Packages
10 | *.nupkg
11 | # The packages folder can be ignored because of Package Restore
12 | **/packages/*
13 | # except build/, which is used as an MSBuild target.
14 | !**/packages/build/
15 |
--------------------------------------------------------------------------------
/AST/CAccess.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CAccess : CExpression
7 | {
8 | private CToken referenceToken;
9 | private bool isRootAccess;
10 | private bool isMemberSource;
11 | private bool isCallExplicit;
12 | private bool isCallImplicit;
13 | private CNode referenceTarget;
14 |
15 |
16 | public CAccess(CToken tok, CToken item)
17 | : base(tok)
18 | {
19 | referenceToken = item;
20 | isMemberSource = false;
21 | isRootAccess = true;
22 | }
23 |
24 | public bool IsRootAccess
25 | {
26 | get { return isRootAccess; }
27 | protected set { isRootAccess = value; }
28 | }
29 |
30 | public bool IsMemberSource
31 | {
32 | get { return isMemberSource; }
33 | set { isMemberSource = value; }
34 | }
35 |
36 | public CNode ReferenceTarget
37 | {
38 | get { return referenceTarget; }
39 | set { referenceTarget = value; }
40 | }
41 |
42 | public CToken ReferenceToken
43 | {
44 | get { return referenceToken; }
45 | protected set { referenceToken = value; }
46 | }
47 |
48 | ///
49 | /// Both IsCallExplicit and IsCallImplicit exist. However, they are not mutually exclusive opposites, so they cannot
50 | /// be condensed down into one method.
51 | ///
52 | public bool IsCallExplicit
53 | {
54 | get { return isCallExplicit; }
55 | set { isCallExplicit = value; }
56 | }
57 |
58 | ///
59 | /// Both IsCallExplicit and IsCallImplicit exist. However, they are not mutually exclusive opposites, so they cannot
60 | /// be condensed down into one method.
61 | ///
62 | public bool IsCallImplicit
63 | {
64 | get { return isCallImplicit; }
65 | set { isCallImplicit = value; }
66 | }
67 |
68 | public override void Accept(IVisitor visit)
69 | {
70 | visit.VisitAccess(this);
71 | }
72 |
73 | public override bool IsConstant
74 | {
75 | get
76 | {
77 | return (ReferenceTarget is CConst) || (ReferenceTarget is CClassConst) || ((ReferenceTarget is CExpression) && ((CExpression)ReferenceTarget).IsConstant);
78 | }
79 | }
80 |
81 | public bool ForceGlobalAccess
82 | {
83 | get;
84 | set;
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/AST/CArgument.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CArgument : CVariableBase, IVariable
7 | {
8 | private CToken direction;
9 |
10 | private Mono.Cecil.ParameterDefinition cecilParameter;
11 |
12 | private bool indexerValueArgument = false;
13 |
14 | public bool IndexerValueArgument
15 | {
16 | get { return indexerValueArgument; }
17 | set { indexerValueArgument = value; }
18 | }
19 |
20 | public Mono.Cecil.ParameterDefinition CecilParameter
21 | {
22 | get { return cecilParameter; }
23 | set { cecilParameter = value; }
24 | }
25 |
26 | public CArgument(CToken direction, CToken name, CTypeRef tref)
27 | : base(name)
28 | {
29 | this.direction = direction;
30 | this.name = name;
31 | base.LoadType(tref);
32 | }
33 |
34 | public bool Optional
35 | {
36 | get { return Attributes.contains("optional"); }
37 | }
38 |
39 | // Optional is a reserved word in Wasabi
40 | public bool IsOptional
41 | {
42 | get { return Optional; }
43 | }
44 |
45 | public CExpression DefaultValue
46 | {
47 | get
48 | {
49 | if (Attributes.contains("optional"))
50 | {
51 | CAttribute attrib = Attributes["optional"];
52 | if (attrib.Parameters.Unnamed.Count != 0)
53 | return (CExpression)attrib.Parameters[0];
54 | }
55 | return null;
56 | }
57 | }
58 |
59 | public CToken Direction
60 | {
61 | get { return direction; }
62 | }
63 |
64 | public override bool IsField
65 | {
66 | get { return false; }
67 | set { throw new NotImplementedException(); }
68 | }
69 |
70 | public override void Accept(IVisitor visitor)
71 | {
72 | }
73 |
74 | public string ToArgumentString()
75 | {
76 | string s1 = "";
77 | if (Optional) s1 = "Optional ";
78 | string s2 = "";
79 | if (Direction.Value == "byref")
80 | s2 = "ByRef ";
81 | else if (Direction.Value == "byval")
82 | s2 = "ByVal ";
83 | string s3 = "";
84 | if (Type != null && Type.TypeName != null && !String.IsNullOrEmpty(Type.TypeName.RawValue))
85 | {
86 | string sName = Type.TypeName.RawValue;
87 | string sParens = "";
88 | while (sName.EndsWith("()"))
89 | {
90 | sParens += "()";
91 | sName = sName.Substring(0, sName.Length - 2);
92 | }
93 | s3 = sParens + " As [" + sName + "]";
94 | }
95 | return s1 + s2 + Name.RawValue + s3;
96 | }
97 |
98 | public string ToParameterString()
99 | {
100 | return Name.RawValue;
101 | }
102 |
103 | public string ToTypeString()
104 | {
105 | string sTypeName = Type.TypeName.RawValue;
106 |
107 | string sParens = "";
108 | while (sTypeName.EndsWith("()"))
109 | {
110 | sParens += "[]";
111 | sTypeName = sTypeName.Substring(0, sTypeName.Length - 2);
112 | }
113 |
114 | System.Type systype = System.Type.GetType("System." + sTypeName);
115 | if (systype != null)
116 | return systype.FullName + sParens;
117 | else
118 | return sTypeName + sParens;
119 | }
120 | }
121 | }
--------------------------------------------------------------------------------
/AST/CArgumentList.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace FogCreek.Wasabi.AST
7 | {
8 | public class CArgumentList : IEnumerable
9 | {
10 | private Dictionary argTable;
11 | private List args = new List();
12 | private bool _semanticallyComplete = false;
13 | private int? minParams;
14 | private int? maxParams;
15 |
16 | public void Add(CArgument arg)
17 | {
18 | minParams = maxParams = null;
19 | args.Add(arg);
20 | }
21 |
22 | public CArgument this[int ix]
23 | {
24 | get { return args[ix]; }
25 | }
26 |
27 | public CArgument this[string name]
28 | {
29 | get
30 | {
31 | BuildArgTable();
32 | CArgument arg = null;
33 | argTable.TryGetValue(name, out arg);
34 | return arg;
35 | }
36 | }
37 |
38 | private void BuildArgTable()
39 | {
40 | if (argTable != null) return;
41 | argTable = new Dictionary(StringComparer.InvariantCultureIgnoreCase);
42 | foreach (CArgument arg in args)
43 | {
44 | argTable[arg.Name.Value] = arg;
45 | }
46 | }
47 |
48 | public CArgumentList GetRange(int index, int count)
49 | {
50 | CArgumentList newlist = new CArgumentList();
51 | newlist.args = args.GetRange(index, count);
52 | return newlist;
53 | }
54 |
55 | public int MinAllowedParameters
56 | {
57 | get
58 | {
59 | if (!minParams.HasValue)
60 | {
61 | GetMinMax();
62 | }
63 | return minParams.Value;
64 | }
65 | }
66 |
67 | public int MaxAllowedParameters
68 | {
69 | get
70 | {
71 | if (!maxParams.HasValue)
72 | {
73 | GetMinMax();
74 | }
75 | return maxParams.Value;
76 | }
77 | }
78 |
79 | private void GetMinMax()
80 | {
81 | maxParams = 0;
82 | minParams = 0;
83 | foreach (CArgument arg in args)
84 | {
85 | bool paramarray = arg.Attributes.contains("paramarray");
86 | if (!arg.Optional && !paramarray)
87 | minParams++;
88 | if (!paramarray)
89 | maxParams++;
90 | else
91 | maxParams = int.MaxValue >> 1;
92 | }
93 | }
94 |
95 | public int Count
96 | {
97 | get { return args.Count; }
98 | }
99 |
100 | public bool SemanticallyComplete()
101 | {
102 | return _semanticallyComplete;
103 | }
104 |
105 | public void SetSemanticallyComplete()
106 | {
107 | _semanticallyComplete = true;
108 | }
109 |
110 | public void ResetSemanticallyComplete()
111 | {
112 | _semanticallyComplete = false;
113 | }
114 |
115 | #region IEnumerable Members
116 |
117 | IEnumerator IEnumerable.GetEnumerator()
118 | {
119 | return args.GetEnumerator();
120 | }
121 |
122 | #endregion
123 |
124 | #region IEnumerable Members
125 |
126 | IEnumerator IEnumerable.GetEnumerator()
127 | {
128 | return args.GetEnumerator();
129 | }
130 |
131 | #endregion
132 |
133 | public IEnumerable Nodes()
134 | {
135 | foreach (CArgument arg in args)
136 | yield return arg;
137 | }
138 |
139 | public string ToArgumentString()
140 | {
141 | List sargs = args.ConvertAll(delegate(CArgument arg) { return arg.ToArgumentString(); });
142 | return String.Join(", ", sargs.ToArray());
143 | }
144 |
145 | public string ToParameterString()
146 | {
147 | List sargs = args.ConvertAll(delegate(CArgument arg) { return arg.ToParameterString(); });
148 | return String.Join(", ", sargs.ToArray());
149 | }
150 |
151 | public string ToTypeString()
152 | {
153 | List sargs = args.ConvertAll(delegate(CArgument arg) { return arg.ToTypeString(); });
154 | return String.Join(", ", sargs.ToArray());
155 | }
156 |
157 | internal bool Contains(string p)
158 | {
159 | foreach (CArgument arg in args)
160 | if (arg.Name.Value == p)
161 | return true;
162 | return false;
163 | }
164 |
165 | internal int IndexOf(CArgument arg)
166 | {
167 | return args.IndexOf(arg);
168 | }
169 | }
170 | }
--------------------------------------------------------------------------------
/AST/CArrayClass.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CArrayType : CClass
7 | {
8 | private static int i = 1;
9 |
10 | private int dims;
11 | protected CTypeRef indexType;
12 | private int id;
13 | private CTypeRef itemType;
14 |
15 | protected virtual string NamePrefix
16 | {
17 | get { return "Array"; }
18 | }
19 |
20 | public override CAttributeList Attributes
21 | {
22 | get
23 | {
24 | CAttributeList cal = base.Attributes;
25 | if (!cal.contains("ExecuteAnywhere") && !cal.contains("ExecuteOnClient") && !cal.contains("ExecuteOnServer") && !cal.contains("ExecuteAtCompiler"))
26 | cal.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(this, CProgram.Global.FindClass("ExecuteAnywhereAttribute")));
27 | return cal;
28 | }
29 | }
30 |
31 | protected virtual string Open { get { return "("; } }
32 | protected virtual string Close { get { return ")"; } }
33 |
34 | public virtual CTypeRef ItemType
35 | {
36 | get { return itemType; }
37 | set
38 | {
39 | itemType.InternalLoad(value);
40 | if (itemType.Resolved)
41 | SetSemanticallyComplete();
42 |
43 | if (ReferenceEquals(value.ActualType, this))
44 | throw new InvalidOperationException("Array ItemType circular reference");
45 |
46 |
47 | string name = (itemType.Resolved ? "" : NamePrefix)
48 | + (itemType.TypeName != null ? itemType.TypeName.RawValue : id.ToString())
49 | + Open + new String(',', dims-1) + Close;
50 | NameToken = CToken.Identifer(NameToken, name, name);
51 |
52 | foreach (CArrayType link in linked)
53 | {
54 | if (link.ItemType.Resolved && link.ItemType != this.ItemType)
55 | throw new InvalidOperationException("IndexedType missinferred");
56 |
57 | if (!link.ItemType.Resolved)
58 | link.itemType = value;
59 | }
60 | }
61 | }
62 |
63 | public virtual bool CanBeRedimed
64 | {
65 | get { return true; }
66 | }
67 |
68 | public CTypeRef IndexType
69 | {
70 | get { return indexType; }
71 | }
72 |
73 | public int Dimensions
74 | {
75 | get { return dims; }
76 | }
77 |
78 | public CArrayType(int dims)
79 | : base("Array<" + (++i) + "," + dims + ">", false)
80 | {
81 | id = i;
82 |
83 | this.dims = dims;
84 | IsObject = false;
85 | indexType = new CTypeRef(this, BuiltIns.Int32);
86 | itemType = new CTypeRef(this);
87 |
88 | if (Compiler.Current != null)
89 | CProgram.Global.AddArray(this);
90 | }
91 |
92 | public override CTypeRef BaseClass
93 | {
94 | get
95 | {
96 | if (NamePrefix == "Array" && (!base.BaseClass.Resolved || base.BaseClass.ActualType == BuiltIns.Variant))
97 | base.ForceSetBaseClass(CProgram.Global.FindClass("System.Array"));
98 | return base.BaseClass;
99 | }
100 | }
101 |
102 | public CArrayType(CTypeRef type, int dims)
103 | : this(dims)
104 | {
105 | ItemType = type;
106 | }
107 |
108 | protected override bool canArrayConvert(CArrayType klass)
109 | {
110 | if (IndexType == klass.IndexType && ItemType.Resolved)
111 | return ItemType.ActualType.canConvertTo(klass.ItemType);
112 | return false;
113 | }
114 |
115 | public override bool Equals(Object obj)
116 | {
117 | if (!(obj is CArrayType))
118 | return false;
119 |
120 | if (ReferenceEquals(obj, this))
121 | return true;
122 |
123 | CArrayType other = (CArrayType)obj;
124 |
125 | if (NamePrefix != other.NamePrefix)
126 | return false;
127 |
128 | if (!itemType.Resolved || !other.itemType.Resolved)
129 | return false;
130 |
131 | if (!indexType.Equals(other.indexType))
132 | return false;
133 |
134 | if (dims != other.dims)
135 | return false;
136 |
137 | return itemType.Equals(other.itemType);
138 | }
139 |
140 | public override int GetHashCode()
141 | {
142 | return 123456789;
143 | }
144 |
145 | List linked = new List();
146 | internal void Link(CArrayType aFrom)
147 | {
148 | linked.Add(aFrom);
149 | }
150 | }
151 | }
--------------------------------------------------------------------------------
/AST/CAsst.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | // this class is for statements in the original vb code that are assignment statements.
7 | // assignment statements have a left hand side and a right hand side
8 | public class CAssignment : CStatement, INodeParent
9 | {
10 | private CAccess lhs; // the left hand side of the assignment statement
11 | private CExpression rhs; // the right hand side of it
12 |
13 | // this is a special case from the normal object types. we are actually being a given an
14 | // object of type CExpression to parse rather than just the lex stream.
15 | public CAssignment(CToken token)
16 | : base(token) {}
17 |
18 | public CAccess Target
19 | {
20 | get { return lhs; }
21 | set
22 | {
23 | lhs = value;
24 | lhs.Parent = this;
25 | lhs.LhsAssignmentTarget = true;
26 | }
27 | }
28 |
29 | public CExpression Source
30 | {
31 | get { return rhs; }
32 | set
33 | {
34 | rhs = value;
35 | rhs.Parent = this;
36 | rhs.RhsAssignmentSource = true;
37 | }
38 | }
39 |
40 | public override void Accept(IVisitor visitor)
41 | {
42 | visitor.VisitAssignment(this);
43 | }
44 |
45 | void INodeParent.Replace(CNode child, CNode newchild)
46 | {
47 | if (lhs == child)
48 | lhs = (CAccess)newchild;
49 | if (rhs == child)
50 | rhs = (CExpression)newchild;
51 | newchild.Parent = this;
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/AST/CAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace FogCreek.Wasabi.AST
4 | {
5 | public class CAttribute : CNode
6 | {
7 | private readonly string name;
8 | private readonly CToken nameToken;
9 | private readonly CParameters parameters;
10 |
11 | public CAttribute(CToken name, CParameters parameters, CTypeRef ctr)
12 | : base(name)
13 | {
14 | this.name = name.Value;
15 | nameToken = name;
16 | this.parameters = parameters ?? new CParameters();
17 | LoadType(new CTypeRef(this, ctr));
18 | }
19 |
20 | public string Name
21 | {
22 | get { return name; }
23 | }
24 |
25 | public CToken NameToken
26 | {
27 | get { return nameToken; }
28 | }
29 |
30 | public CParameters Parameters
31 | {
32 | get { return parameters; }
33 | }
34 |
35 | public override void Accept(IVisitor visitor)
36 | {
37 | visitor.VisitAttribute(this);
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/AST/CAttributeList.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | namespace FogCreek.Wasabi.AST
6 | {
7 | public class CAttributeList : IEnumerable
8 | {
9 | internal List list = new List();
10 |
11 | public int Count
12 | {
13 | get { return list.Count; }
14 | }
15 |
16 | public void Add(CToken name, CTypeRef ctr)
17 | {
18 | Add(name, null, ctr);
19 | }
20 |
21 | public void Add(CToken name, CParameters parameters, CTypeRef ctr)
22 | {
23 | list.Add(new CAttribute(name, parameters, ctr));
24 | }
25 |
26 | public void Add(CAttributeList attribs)
27 | {
28 | if (attribs != null)
29 | list.AddRange(attribs.list);
30 | }
31 |
32 | protected void Add(CAttribute attrib)
33 | {
34 | list.Add(attrib);
35 | }
36 |
37 | private static readonly CAttributeList empty = new CAttributeList();
38 |
39 | public CAttributeList getList(String name)
40 | {
41 | if (list.Count == 0)
42 | return empty;
43 |
44 | CAttributeList result = new CAttributeList();
45 | foreach (CAttribute attribute in list)
46 | {
47 | if (NameEquals(attribute.Name, name))
48 | result.Add(attribute);
49 | }
50 |
51 | return result;
52 | }
53 |
54 | private bool NameEquals(string p, string name)
55 | {
56 | return p.Equals(name, StringComparison.OrdinalIgnoreCase) ||
57 | (p + "Attribute").Equals(name, StringComparison.OrdinalIgnoreCase) ||
58 | p.Equals(name + "Attribute", StringComparison.OrdinalIgnoreCase);
59 | }
60 |
61 | public CAttributeList getList()
62 | {
63 | if (list.Count == 0)
64 | return empty;
65 |
66 | CAttributeList result = new CAttributeList();
67 | foreach (CAttribute attribute in list)
68 | result.Add(attribute);
69 |
70 | return result;
71 | }
72 |
73 | public bool contains(String name)
74 | {
75 | if (list.Count == 0)
76 | return false;
77 | name = name.ToLower();
78 | for (int i = 0; i < list.Count; i++)
79 | {
80 | if (NameEquals(this[i].Name, name))
81 | return true;
82 | }
83 | return false;
84 | }
85 |
86 |
87 | public bool containsMultiple(string name)
88 | {
89 | if (list.Count < 2)
90 | return false;
91 | name = name.ToLower();
92 |
93 | int found = 0;
94 |
95 | for (int i = 0; i < list.Count; i++)
96 | {
97 | if (NameEquals(this[i].Name, name))
98 | found++;
99 | if (found > 1)
100 | return true;
101 | }
102 | return false;
103 | }
104 |
105 | public bool CanVisit(NodeStateMode mode, bool fAlsoExistsOnClient)
106 | {
107 | if (mode == NodeStateMode.Client)
108 | {
109 | return contains("executeanywhere")
110 | || contains("executeonclient")
111 | || contains("executeonserver")
112 | || (fAlsoExistsOnClient && contains("alsoexistsonclient"));
113 | }
114 | else if (mode == NodeStateMode.Server)
115 | {
116 | return contains("executeanywhere")
117 | || !contains("executeonclient");
118 | }
119 | else
120 | throw new InvalidOperationException("Unknown mode!");
121 | }
122 |
123 |
124 | public CAttribute this[object nameOrIx]
125 | {
126 | get
127 | {
128 | if (nameOrIx is String)
129 | return this[(String)nameOrIx];
130 | else
131 | return this[Convert.ToInt32(nameOrIx)];
132 | }
133 | }
134 |
135 | public CAttribute this[string name]
136 | {
137 | get
138 | {
139 | if (list.Count == 0)
140 | return null;
141 | for (int i = 0; i < list.Count; i++)
142 | {
143 | if (this[i].Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
144 | return this[i];
145 | }
146 | for (int i = 0; i < list.Count; i++)
147 | {
148 | if ((this[i].Name + "Attribute").Equals(name, StringComparison.InvariantCultureIgnoreCase) || (this[i].Name).Equals(name + "Attribute", StringComparison.InvariantCultureIgnoreCase))
149 | return this[i];
150 | }
151 | return null;
152 | }
153 | }
154 |
155 | public CAttribute this[int ix]
156 | {
157 | get { return list[ix]; }
158 | }
159 |
160 | ///
161 | ///Returns an enumerator that iterates through the collection.
162 | ///
163 | ///
164 | ///
165 | ///A that can be used to iterate through the collection.
166 | ///
167 | ///1
168 | IEnumerator IEnumerable.GetEnumerator()
169 | {
170 | return list.GetEnumerator();
171 | }
172 |
173 | ///
174 | ///Returns an enumerator that iterates through a collection.
175 | ///
176 | ///
177 | ///
178 | ///An object that can be used to iterate through the collection.
179 | ///
180 | ///2
181 | IEnumerator IEnumerable.GetEnumerator()
182 | {
183 | return list.GetEnumerator();
184 | }
185 | }
186 | }
--------------------------------------------------------------------------------
/AST/CBaseAccess.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CBaseAccess : CAccess
7 | {
8 | public CBaseAccess(CToken tok)
9 | : base(tok, tok)
10 | {
11 | }
12 |
13 | public override void Accept(IVisitor visit)
14 | {
15 | visit.VisitBaseAccess(this);
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/AST/CBinaryOperator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public abstract class CBinaryOperator : CExpression, INodeParent
7 | {
8 | private CToken operation;
9 | private CExpression lhs;
10 | private CExpression rhs;
11 |
12 | public CBinaryOperator(CToken tok, CExpression lhs, CExpression rhs)
13 | : base(tok)
14 | {
15 | operation = tok;
16 | this.lhs = lhs;
17 | this.rhs = rhs;
18 | lhs.Parent = this;
19 | rhs.Parent = this;
20 | }
21 |
22 | public override bool IsConstant
23 | {
24 | get
25 | {
26 | return lhs.IsConstant && rhs.IsConstant;
27 | }
28 | }
29 |
30 | public CToken Operation
31 | {
32 | get { return operation; }
33 | }
34 |
35 | public CExpression Left
36 | {
37 | get { return lhs; }
38 | }
39 |
40 | public CExpression Right
41 | {
42 | get { return rhs; }
43 | }
44 |
45 | void INodeParent.Replace(CNode child, CNode newchild)
46 | {
47 | if (lhs == child)
48 | lhs = (CExpression)newchild;
49 | if (rhs == child)
50 | rhs = (CExpression)newchild;
51 | newchild.Parent = this;
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/AST/CCase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | // this class is for the specific cases of a switch statement
7 | public class CCase : CStatement, INodeParent
8 | {
9 | private CExpression m_value; // in the line case('prephase') then 'prephase' is the vaue
10 | private CStatementBlock statements; // the statements to be executed in this case of the switch
11 | private bool elseCaseFlag; // flag indicating if this case is the default case
12 |
13 |
14 | // if statements is null, that means there are no statements. meaning this case uses the statements
15 | // of the case below it. so dont put a break point. eg:
16 | // switch (color) {
17 | // case (red):
18 | // case (blue):
19 | // print("its red or blue);
20 | // break;
21 | //
22 | public CCase(CToken token, CExpression val)
23 | : base(token)
24 | {
25 | m_value = val;
26 | m_value.Parent = this;
27 | statements = null;
28 | }
29 |
30 | // this is the constructor when you actually need to parse all the statements of a case
31 | // until you hit the next case
32 | public CCase(CToken token, CExpression val, CStatementBlock block)
33 | : base(token)
34 | {
35 | m_value = val;
36 | elseCaseFlag = val == null;
37 | if (!elseCaseFlag)
38 | m_value.Parent = this;
39 | statements = block;
40 | }
41 |
42 | public bool IsElseCase
43 | {
44 | get { return elseCaseFlag; }
45 | }
46 |
47 | public CStatementBlock Statements
48 | {
49 | get { return statements; }
50 | }
51 |
52 | public CExpression Value
53 | {
54 | get { return m_value; }
55 | }
56 |
57 | public override void Accept(IVisitor visitor)
58 | {
59 | visitor.VisitCase(this);
60 | }
61 |
62 | void INodeParent.Replace(CNode child, CNode newchild)
63 | {
64 | if (child == m_value)
65 | m_value = (CExpression)newchild;
66 | newchild.Parent = this;
67 | }
68 | }
69 | }
--------------------------------------------------------------------------------
/AST/CCast.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace FogCreek.Wasabi.AST
6 | {
7 | public class CCast : CParenExpression
8 | {
9 | public CCast(CTypeRef type, CExpression exp)
10 | : base(type.TypeName, exp)
11 | {
12 | LoadType(type);
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/AST/CCatch.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace FogCreek.Wasabi.AST
6 | {
7 | public class CCatch : CStatement
8 | {
9 | CVariable pivot;
10 | CStatementBlock statements = new CStatementBlock();
11 |
12 | public CVariable Pivot
13 | {
14 | get { return pivot; }
15 | set { pivot = value; }
16 | }
17 |
18 | public CStatementBlock Statements
19 | {
20 | get { return statements; }
21 | }
22 |
23 | public CCatch(CToken tok)
24 | : base(tok) { }
25 |
26 | public override void Accept(IVisitor visitor)
27 | {
28 | visitor.VisitCatch(this);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/AST/CClassConst.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace FogCreek.Wasabi.AST
4 | {
5 | public class CClassConst : CMember
6 | {
7 | CClass declaringClass;
8 | CConst myConst;
9 | public CClassConst(CClass declaringClass, CConst myConst)
10 | : base(myConst.Token, myConst.Name.Value, "const", 1, false)
11 | {
12 | this.declaringClass = declaringClass;
13 | this.myConst = myConst;
14 | Declared[0] = myConst;
15 | myConst.ClassConst = this;
16 | }
17 |
18 | public CConst Constant
19 | {
20 | get { return myConst; }
21 | }
22 |
23 | public override TokenTypes Visibility
24 | {
25 | get { return TokenTypes.visPublic; }
26 | }
27 |
28 | public override CClass DeclaringClass
29 | {
30 | get { return declaringClass; }
31 | }
32 |
33 | public override bool SemanticallyComplete
34 | {
35 | get { return myConst.SemanticallyComplete; }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/AST/CComment.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 |
7 | public class CComment : CStatement
8 | {
9 | private String commentString;
10 |
11 | public CComment(CToken token, String com)
12 | : base(token)
13 | {
14 | commentString = com;
15 | }
16 |
17 | public string Text
18 | {
19 | get { return commentString; }
20 | }
21 |
22 | public override void Accept(IVisitor visitor)
23 | {
24 | visitor.VisitComment(this);
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/AST/CComparison.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CComparison : CBinaryOperator
7 | {
8 | public CComparison(CToken tok, CExpression lhs, CExpression rhs)
9 | : base(tok, lhs, rhs)
10 | {
11 | base.LoadType(BuiltIns.Boolean);
12 | }
13 |
14 | public override void Accept(IVisitor visit)
15 | {
16 | visit.VisitComparison(this);
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/AST/CConcat.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 |
7 | public class CConcat : CBinaryOperator
8 | {
9 | public CConcat(CToken tok, CExpression lhs, CExpression rhs)
10 | : base(tok, lhs, rhs)
11 | {
12 | }
13 |
14 | private delegate bool fIsConst(object o);
15 |
16 | public override bool IsConstant
17 | {
18 | get
19 | {
20 | CClass __string = BuiltIns.String;
21 | fIsConst isConst = delegate(object o)
22 | {
23 | if (o is CConstantExpression)
24 | return ((CConstantExpression)o).Type == __string;
25 | if (o is CConcat)
26 | return ((CConcat)o).IsConstant;
27 | return false;
28 | };
29 | return isConst(Left) && isConst(Right);
30 | }
31 | }
32 |
33 | private delegate string fGetConst(object o);
34 |
35 | public string ConstantValue
36 | {
37 | get
38 | {
39 | if (!IsConstant)
40 | throw new InvalidOperationException("Not a constant node");
41 | fGetConst getConst = delegate(object o)
42 | {
43 | if (o is CConstantExpression)
44 | return ((CConstantExpression)o).Value.Value;
45 | if (o is CConcat)
46 | return ((CConcat)o).ConstantValue;
47 | throw new InvalidOperationException("Not a constant node");
48 | };
49 | return getConst(Left) + getConst(Right);
50 | }
51 | }
52 |
53 | public override void Accept(IVisitor visitor)
54 | {
55 | visitor.VisitConcat(this);
56 | }
57 | }
58 | }
--------------------------------------------------------------------------------
/AST/CConst.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 |
7 | // this class is for statements in vbscript that define constants
8 | public class CConst : CStatement, INodeParent, IAttributed, IVariable
9 | {
10 | private CToken constName;
11 | private CExpression constValue;
12 |
13 | public CConst(CToken token, CToken name, CExpression exp)
14 | : base(token)
15 | {
16 | constName = name;
17 | constValue = exp;
18 | constValue.Parent = this;
19 | }
20 |
21 | public CToken Name
22 | {
23 | get { return constName; }
24 | }
25 |
26 | public CExpression Value
27 | {
28 | get { return constValue; }
29 | }
30 |
31 | void INodeParent.Replace(CNode child, CNode newchild)
32 | {
33 | if (child == constValue)
34 | constValue = (CExpression)newchild;
35 | newchild.Parent = this;
36 | }
37 |
38 | public override void Accept(IVisitor visitor)
39 | {
40 | visitor.VisitConst(this);
41 | }
42 |
43 | private CClassConst ccc;
44 | public CClassConst ClassConst
45 | {
46 | get { return ccc; }
47 | set { ccc = value; }
48 | }
49 |
50 | #region IAttributed Members
51 |
52 | CAttributeList attributes = new CAttributeList();
53 | public CAttributeList Attributes
54 | {
55 | get { return attributes; }
56 | }
57 |
58 | #endregion
59 |
60 | #region IVariable Members
61 |
62 |
63 | string IVariable.Name
64 | {
65 | get { return constName.Value; }
66 | }
67 |
68 | public bool IsArray
69 | {
70 | get { return false; }
71 | }
72 |
73 | public bool AccessedBeforeUsed
74 | {
75 | get { return false; }
76 | }
77 |
78 | public int AssignmentCount
79 | {
80 | get { return 1; }
81 | }
82 |
83 | int accesses;
84 | public int AccessCount
85 | {
86 | get { return accesses; }
87 | }
88 |
89 | public string RawName
90 | {
91 | get { return constName.RawValue; }
92 | }
93 |
94 | public void incAssignmentCount(CClass currentclass, CFunction currentfunction)
95 | {
96 | throw new Exception("Const variable is readonly");
97 | }
98 |
99 | public void incAccessCount(CClass currentclass, CFunction currentfunction)
100 | {
101 | accesses++;
102 | }
103 |
104 | public bool canAssign(CClass currentclass, CFunction currentfunction)
105 | {
106 | return false;
107 | }
108 |
109 | public void SetExternallyReferenced()
110 | {
111 | throw new NotImplementedException();
112 | }
113 |
114 | #endregion
115 |
116 | public CClass ContainingClass { get; set; }
117 |
118 | public CFunction ContainingFunction { get; set; }
119 | }
120 | }
--------------------------------------------------------------------------------
/AST/CConstantExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CConstantExpression : CExpression
7 | {
8 | private CToken m_value;
9 |
10 | public CConstantExpression(CToken tok)
11 | : base(tok)
12 | {
13 | m_value = tok;
14 | CClass type = null;
15 | switch (tok.TokenType)
16 | {
17 | case TokenTypes.number:
18 | int i;
19 | if (Int32.TryParse(tok.Value, out i) || tok.Value.StartsWith("0x"))
20 | type = BuiltIns.Int32;
21 | else
22 | type = BuiltIns.Double;
23 | break;
24 |
25 | case TokenTypes.str:
26 | type = BuiltIns.String;
27 | break;
28 |
29 | case TokenTypes.character:
30 | type = BuiltIns.Character;
31 | break;
32 |
33 | case TokenTypes.pound:
34 | type = BuiltIns.Date;
35 | break;
36 |
37 | case TokenTypes.keyword:
38 | if (tok.Value == "true")
39 | type = BuiltIns.Boolean;
40 | else if (tok.Value == "false")
41 | type = BuiltIns.Boolean;
42 | else if (tok.Value == "nothing")
43 | type = BuiltIns.Nothing;
44 | else if (tok.Value == "dbnull")
45 | type = BuiltIns.DbNull;
46 | break;
47 | }
48 | if (type != null)
49 | base.LoadType(type);
50 | }
51 |
52 | public override bool IsConstant
53 | {
54 | get
55 | {
56 | return true;
57 | }
58 | }
59 |
60 | public CToken Value
61 | {
62 | get { return m_value; }
63 | }
64 |
65 | public override void Accept(IVisitor visit)
66 | {
67 | visit.VisitConstantExpression(this);
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/AST/CDefaultAccess.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CDefaultAccess : CAccess, INodeParent
7 | {
8 | private CAccess m_targetAccess;
9 | private CParameters parameters;
10 | private bool realDefaultMethodCall = false;
11 |
12 | public CDefaultAccess(CToken tok, CAccess item, CParameters parameters)
13 | : base(tok, tok)
14 | {
15 | m_targetAccess = item;
16 | m_targetAccess.Parent = this;
17 | this.parameters = parameters;
18 | this.parameters.Parent = this;
19 | item.IsCallExplicit = true;
20 | IsRootAccess = false;
21 | }
22 |
23 | public CAccess TargetAccess
24 | {
25 | get { return m_targetAccess; }
26 | }
27 |
28 | public CParameters Parameters
29 | {
30 | get { return parameters; }
31 | }
32 |
33 | public override void Accept(IVisitor visit)
34 | {
35 | visit.VisitDefaultAccess(this);
36 | }
37 |
38 | void INodeParent.Replace(CNode child, CNode newchild)
39 | {
40 | if (child == m_targetAccess)
41 | m_targetAccess = (CAccess)newchild;
42 | newchild.Parent = this;
43 | m_targetAccess.IsCallExplicit = true;
44 | }
45 |
46 | public bool IsRealDefaultMethodCall
47 | {
48 | get { return realDefaultMethodCall; }
49 | set { realDefaultMethodCall = value; }
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/AST/CDictionaryType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections;
4 |
5 | namespace FogCreek.Wasabi.AST
6 | {
7 | public class CDictionaryType : CArrayType
8 | {
9 | private bool generatingMembers;
10 | private bool generatedMembers;
11 |
12 | protected override string NamePrefix
13 | {
14 | get { return "Dictionary"; }
15 | }
16 |
17 | protected override string Open { get { return "{"; } }
18 | protected override string Close { get { return "}"; } }
19 |
20 | public override bool CanBeRedimed
21 | {
22 | get { return false; }
23 | }
24 |
25 | public static List Dictionaries = new List();
26 |
27 | public CDictionaryType(CTypeRef type)
28 | : base(type, 1)
29 | {
30 | indexType.InternalLoad(BuiltIns.String);
31 | Dictionaries.Add(this);
32 | IsObject = true;
33 | }
34 |
35 | public override CTypeRef ItemType
36 | {
37 | get { return base.ItemType; }
38 | set
39 | {
40 | base.ItemType = value;
41 |
42 | if (value.Resolved && generatedMembers)
43 | UpdateMembers();
44 | }
45 | }
46 |
47 | private Mono.Cecil.MethodDefinition FindMethod(string name)
48 | {
49 | foreach (Mono.Cecil.MethodDefinition method in CecilType.Methods)
50 | {
51 | if (method.Name == name)
52 | return method;
53 | }
54 | throw new ArgumentOutOfRangeException("name");
55 | }
56 |
57 | private void UpdateMembers()
58 | {
59 | CMethod items = (CMethod)base.LookupMember("items");
60 | ((CArrayType)items.Function.Type.ActualType).ItemType = ItemType;
61 |
62 | CMethod add = (CMethod)base.LookupMember("add");
63 | add.Function.Arguments[1].LoadType(ItemType);
64 |
65 | CProperty item = (CProperty)base.LookupMember("item");
66 | item.LoadType(ItemType);
67 | if (item.GetAccessor != null)
68 | item.GetAccessor.LoadType(ItemType);
69 | if (item.SetAccessor != null)
70 | item.SetAccessor.Arguments[1].LoadType(ItemType);
71 | }
72 |
73 | public override IEnumerable DirectMemberIterator
74 | {
75 | get
76 | {
77 | if (!generatingMembers)
78 | {
79 | GenerateAndResolveMembers();
80 | }
81 | return base.DirectMemberIterator;
82 | }
83 | }
84 |
85 | public override void SetMember(string k, CMember v)
86 | {
87 | if (!generatingMembers)
88 | {
89 | GenerateAndResolveMembers();
90 | }
91 | base.SetMember(k, v);
92 | }
93 |
94 | public override CMember LookupMember(string k)
95 | {
96 | if (!generatingMembers)
97 | {
98 | GenerateAndResolveMembers();
99 | }
100 | return base.LookupMember(k);
101 | }
102 |
103 | private void TryItemTypeFixup()
104 | {
105 | CClass type;
106 | CMethod items = (CMethod)base.LookupMember("items");
107 |
108 | type = ((CArrayType)items.Declared[CProperty.ixGet].Type).ItemType.ActualType;
109 |
110 | if (type == null)
111 | {
112 | CMethod add = (CMethod)base.LookupMember("add");
113 | type = add.Function.Arguments[1].Type.ActualType;
114 | }
115 |
116 | if (type == null)
117 | {
118 | CProperty item = (CProperty)base.LookupMember("item");
119 | type = item.Type.ActualType;
120 | if (type == null && item.GetAccessor != null)
121 | type = item.GetAccessor.Type.ActualType;
122 | if (type == null && item.SetAccessor != null)
123 | type = item.SetAccessor.Arguments[1].Type.ActualType;
124 | }
125 |
126 | if (type != null)
127 | ItemType = new CTypeRef(null, type);
128 | }
129 |
130 | public override bool canConvertTo(CClass klass)
131 | {
132 | if (klass.Name == "progid:scripting.dictionary")
133 | return true;
134 | return base.canConvertTo(klass);
135 | }
136 |
137 | public override CMember DefaultMember
138 | {
139 | get { return LookupMember("item"); }
140 | set { throw new NotImplementedException(); }
141 | }
142 |
143 |
144 | private void GenerateMembers()
145 | {
146 | generatingMembers = true;
147 |
148 | //
149 |
150 | CMethod items = (CMethod)LookupMember("items");
151 | CClass type = new CArrayType(1);
152 | items.LoadType(type);
153 | items.Function.LoadType(type);
154 |
155 | base.Scope.Clear();
156 | foreach (CMember member in InheritedMemberIterator)
157 | {
158 | base.Scope.add(member);
159 | }
160 |
161 | generatingMembers = false;
162 | generatedMembers = true;
163 | }
164 |
165 | public override void Accept(IVisitor visitor)
166 | {
167 | GenerateAndResolveMembers();
168 |
169 | base.Accept(visitor);
170 |
171 | GenerateAndResolveMembers();
172 | }
173 |
174 | public override CScope Scope
175 | {
176 | get
177 | {
178 | GenerateAndResolveMembers();
179 | return base.Scope;
180 | }
181 | }
182 |
183 | private void GenerateAndResolveMembers()
184 | {
185 | if (!generatedMembers)
186 | {
187 | GenerateMembers();
188 | if (ItemType.Resolved)
189 | UpdateMembers();
190 | }
191 | else if (!ItemType.Resolved)
192 | TryItemTypeFixup();
193 | }
194 | }
195 | }
--------------------------------------------------------------------------------
/AST/CDim.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CDim : CStatement, IAttributed
7 | {
8 | private List variables = new List();
9 | private bool inlineComment;
10 |
11 | public CDim(CToken token)
12 | : base(token)
13 | {
14 | }
15 |
16 | public List Variables
17 | {
18 | get { return variables; }
19 | }
20 |
21 | public CAttributeList Attributes
22 | {
23 | get { return variables[0].Attributes; }
24 | }
25 |
26 | public override void Accept(IVisitor visitor)
27 | {
28 | visitor.VisitDim(this);
29 | }
30 |
31 | public bool InlineComment
32 | {
33 | get { return inlineComment; }
34 | set { inlineComment = value; }
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/AST/CDirective.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CDirective : CStatement
7 | {
8 | public CDirective(CToken token)
9 | : base(token)
10 | {
11 | }
12 |
13 | public override void Accept(IVisitor visitor)
14 | {
15 | visitor.VisitDirective(this);
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/AST/CDo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CDo : CStatement, INodeParent
7 | {
8 | private CExpression condition;
9 | private CStatementBlock statements = new CStatementBlock();
10 | private bool bUntil;
11 | private bool postcondition;
12 |
13 | public CDo(CToken token)
14 | : base(token)
15 | {
16 | }
17 |
18 | public CExpression Condition
19 | {
20 | get { return condition; }
21 | set
22 | {
23 | condition = value;
24 | condition.Parent = this;
25 | }
26 | }
27 |
28 | public override void Accept(IVisitor visitor)
29 | {
30 | visitor.VisitDo(this);
31 | }
32 |
33 | public CStatementBlock Statements
34 | {
35 | get { return statements; }
36 | set { statements = value; }
37 | }
38 |
39 | public bool IsDoUntil
40 | {
41 | get { return bUntil; }
42 | set { bUntil = value; }
43 | }
44 |
45 | public bool IsPostConditionLoop
46 | {
47 | get { return postcondition; }
48 | set { postcondition = value; }
49 | }
50 |
51 | void INodeParent.Replace(CNode child, CNode newchild)
52 | {
53 | if (child == condition)
54 | condition = (CExpression)newchild;
55 | newchild.Parent = this;
56 | }
57 | }
58 | }
--------------------------------------------------------------------------------
/AST/CEnum.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Diagnostics;
5 |
6 | namespace FogCreek.Wasabi.AST
7 | {
8 | [DebuggerDisplay("Name: {RawName}")]
9 | public class CEnum : CClass
10 | {
11 | public CEnum(CToken tok, CToken name)
12 | : base(tok, name.RawValue, name.Value, CTypeRef.Empty)
13 | {
14 | IsObject = false;
15 | IsNumeric = true;
16 | }
17 |
18 | public override void Accept(IVisitor visitor)
19 | {
20 | visitor.VisitEnum(this);
21 | }
22 |
23 | internal override void AddInterface(CTypeRef interfaceref)
24 | {
25 | throw new InvalidOperationException("Enums can't have interfaces");
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/AST/CExit.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | // the exit statement in vbscript
7 | public class CExit : CStatement
8 | {
9 | private bool subFlag;
10 | private bool funcFlag;
11 | private String exitWhat;
12 |
13 | public CExit(CToken token, String exitWhat)
14 | : base(token)
15 | {
16 | this.exitWhat = exitWhat;
17 | if (exitWhat == "function")
18 | funcFlag = true;
19 | else if (exitWhat == "sub")
20 | subFlag = true;
21 | }
22 |
23 | public override void Accept(IVisitor visitor)
24 | {
25 | visitor.VisitExit(this);
26 | }
27 |
28 | public bool IsExitSub
29 | {
30 | get { return subFlag; }
31 | set { subFlag = value; }
32 | }
33 |
34 | public bool IsExitFunction
35 | {
36 | get { return funcFlag; }
37 | set { funcFlag = value; }
38 | }
39 |
40 | public String ExitType
41 | {
42 | get { return exitWhat; }
43 | set { exitWhat = value; }
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/AST/CExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public abstract class CExpression : CNode
7 | {
8 | private bool lhsAssignmentTarget;
9 | private bool rhsAssignmentSource;
10 | private bool passedByRef = false;
11 | private CArgument referencedArgument;
12 |
13 | public CExpression(CToken token)
14 | : base(token)
15 | {
16 | }
17 |
18 | public virtual bool IsConstant
19 | {
20 | get { return false; }
21 | }
22 |
23 | public bool IsPassedByRef
24 | {
25 | get { return passedByRef; }
26 | set { passedByRef = value; }
27 | }
28 |
29 | public bool LhsAssignmentTarget
30 | {
31 | get { return lhsAssignmentTarget; }
32 | set { lhsAssignmentTarget = value; }
33 | }
34 |
35 | public bool RhsAssignmentSource
36 | {
37 | get { return rhsAssignmentSource; }
38 | set { rhsAssignmentSource = value; }
39 | }
40 |
41 | public CArgument ReferencedArgument
42 | {
43 | get { return referencedArgument; }
44 | set { referencedArgument = value; }
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/AST/CExpressionStatement.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CExpressionStatement : CStatement, INodeParent
7 | {
8 | private CExpression exp;
9 |
10 | public CExpressionStatement(CExpression exp)
11 | : base(exp.Token)
12 | {
13 | this.exp = exp;
14 | exp.Parent = this;
15 | }
16 |
17 | public CExpression InnerExpression
18 | {
19 | get { return exp; }
20 | }
21 |
22 | public override void Accept(IVisitor visitor)
23 | {
24 | visitor.VisitStatement(this);
25 | }
26 |
27 | void INodeParent.Replace(CNode child, CNode newchild)
28 | {
29 | if (child == exp)
30 | exp = (CExpression)newchild;
31 | newchild.Parent = this;
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/AST/CField.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CField : CMember
7 | {
8 | private CMemberVariable declaration;
9 | private CVariable variable;
10 |
11 | public CField(CVariable var, CMemberVariable declaration)
12 | : base(var.Token, var.Name.Value, "field", 1, false)
13 | {
14 | Declared[0] = var;
15 | variable = var;
16 | var.Field = this;
17 | this.declaration = declaration;
18 | }
19 |
20 | public CField(CField field, bool isUnionMember)
21 | : base(field.Token, field.Name, "field", 1, isUnionMember)
22 | {
23 | this.declaration = field.declaration;
24 | Declared[0] = this.variable = field.variable;
25 | }
26 |
27 | public override bool SemanticallyComplete
28 | {
29 | get { return declaration.SemanticallyComplete; }
30 | }
31 |
32 | public override TokenTypes Visibility
33 | {
34 | get { return declaration.Visibility; }
35 | }
36 |
37 | public override CClass DeclaringClass
38 | {
39 | get { return declaration.DeclaringClass; }
40 | }
41 |
42 | public CMemberVariable MemberDeclaration
43 | {
44 | get { return declaration; }
45 | set { declaration = value; }
46 | }
47 |
48 | public CVariable Variable
49 | {
50 | get { return variable; }
51 | set { variable = value; }
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/AST/CFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CFile : CNode, IAttributed, INodeParent
7 | {
8 | private String filename;
9 | private readonly string fullPathToFile;
10 | private bool includedByExecuteAtCompilerFile = false;
11 | private CAttributeList attribs = new CAttributeList();
12 | private CStatementBlock statements = new CStatementBlock();
13 | private List lambdas = new List();
14 | private List nameSpaceResolutionPrefixes = new List();
15 | private Dictionary classNameAliases = new Dictionary(StringComparer.InvariantCultureIgnoreCase);
16 |
17 | public CFile(String filename, string fullPathToFile)
18 | {
19 | this.filename = filename;
20 | this.fullPathToFile = fullPathToFile;
21 | statements.Parent = this;
22 | }
23 |
24 | public string Filename
25 | {
26 | get { return filename; }
27 | }
28 |
29 | public CStatementBlock Statements
30 | {
31 | get { return statements; }
32 | }
33 |
34 | public CAttributeList Attributes
35 | {
36 | get { return attribs; }
37 | }
38 |
39 | public List Lambdas
40 | {
41 | get { return lambdas; }
42 | }
43 |
44 | public string FullPathToFile
45 | {
46 | get { return fullPathToFile; }
47 | }
48 |
49 | public bool IncludedByExecuteAtCompilerFile
50 | {
51 | get { return includedByExecuteAtCompilerFile; }
52 | set { includedByExecuteAtCompilerFile = value; }
53 | }
54 |
55 | public List NameSpaceResolutionPrefixes
56 | {
57 | get { return nameSpaceResolutionPrefixes; }
58 | }
59 |
60 | public Dictionary ClassNameAliases
61 | {
62 | get { return classNameAliases; }
63 | }
64 |
65 | public override void Accept(IVisitor visitor)
66 | {
67 | visitor.VisitFile(this);
68 | }
69 |
70 | public void Replace(CNode child, CNode newchild)
71 | {
72 | throw new NotImplementedException();
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/AST/CFinally.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace FogCreek.Wasabi.AST
6 | {
7 | public class CFinally : CStatement
8 | {
9 | CStatementBlock statements = new CStatementBlock();
10 |
11 | public CStatementBlock Statements
12 | {
13 | get { return statements; }
14 | }
15 |
16 | public CFinally(CToken tok)
17 | : base(tok)
18 | {
19 | }
20 |
21 | public override void Accept(IVisitor visitor)
22 | {
23 | visitor.VisitFinally(this);
24 | }
25 |
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/AST/CFor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | // vbcscipt for loop statement
7 | public class CFor : CStatement, INodeParent
8 | {
9 | private CAccess forVariable; // like i, or j, or counter
10 | private CExpression init; // the initial value of the var
11 | private CExpression condition; // the final value of the var
12 | private CExpression step; // the expression to add to the var
13 | private CStatementBlock statements = new CStatementBlock();
14 |
15 | public CFor(CToken token, CToken var)
16 | : base(token)
17 | {
18 | forVariable = new CAccess(var, var);
19 | forVariable.Parent = this;
20 | }
21 |
22 | public CExpression Initializer
23 | {
24 | get { return init; }
25 | set
26 | {
27 | init = value;
28 | init.Parent = this;
29 | }
30 | }
31 |
32 | public CExpression Terminator
33 | {
34 | get { return condition; }
35 | set
36 | {
37 | condition = value;
38 | condition.Parent = this;
39 | }
40 | }
41 |
42 | public CExpression Step
43 | {
44 | get { return step; }
45 | set
46 | {
47 | step = value;
48 | step.Parent = this;
49 | }
50 | }
51 |
52 | [Obsolete("Use ForVariable instead")]
53 | public string ForVariableName
54 | {
55 | get { return ForVariableToken.Value; }
56 | }
57 |
58 | [Obsolete("Use ForVariable instead")]
59 | public CToken ForVariableToken
60 | {
61 | get { return forVariable.Token; }
62 | }
63 |
64 | public CAccess ForVariable
65 | {
66 | get { return forVariable; }
67 | }
68 |
69 | public CStatementBlock Statements
70 | {
71 | get { return statements; }
72 | set { statements = value; }
73 | }
74 |
75 | public override void Accept(IVisitor visitor)
76 | {
77 | visitor.VisitFor(this);
78 | }
79 |
80 | void INodeParent.Replace(CNode child, CNode newchild)
81 | {
82 | if (child == init)
83 | init = (CExpression)newchild;
84 | if (child == condition)
85 | condition = (CExpression)newchild;
86 | if (child == step)
87 | step = (CExpression)newchild;
88 | newchild.Parent = this;
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/AST/CForEach.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CForEach : CStatement, INodeParent
7 | {
8 | private CAccess forVariable;
9 | private CExpression group;
10 | private CStatementBlock statements = new CStatementBlock();
11 |
12 | public CForEach(CToken token, CToken var)
13 | : base(token)
14 | {
15 | forVariable = new CAccess(var, var);
16 | }
17 |
18 | public CExpression Enumerable
19 | {
20 | get { return group; }
21 | set
22 | {
23 | group = value;
24 | group.Parent = this;
25 | }
26 | }
27 |
28 | [Obsolete("Use ForVariable instead")]
29 | public string ForVariableName
30 | {
31 | get { return ForVariable.Token.Value; }
32 | }
33 |
34 | [Obsolete("Use ForVariable instead")]
35 | public CToken ForVariableToken
36 | {
37 | get { return forVariable.Token; }
38 | }
39 |
40 | public CAccess ForVariable
41 | {
42 | get { return forVariable; }
43 | }
44 |
45 | public CStatementBlock Statements
46 | {
47 | get { return statements; }
48 | set { statements = value; }
49 | }
50 |
51 | public override void Accept(IVisitor visitor)
52 | {
53 | visitor.VisitForEach(this);
54 | }
55 |
56 | void INodeParent.Replace(CNode child, CNode newchild)
57 | {
58 | if (child == group)
59 | group = (CExpression)newchild;
60 | newchild.Parent = this;
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/AST/CFunctionType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CFunctionType : CClass
7 | {
8 | private readonly CFunction target;
9 | private readonly bool declarationOnly;
10 |
11 | public CFunction Target
12 | {
13 | get { return target; }
14 | }
15 |
16 | public CFunctionType(CToken token, CFunction function, bool declarationOnly)
17 | : base(token, function.TypeSignature)
18 | {
19 | target = function;
20 | this.declarationOnly = declarationOnly;
21 |
22 | CMethod method = new CMethod(function);
23 | DefaultMember = method;
24 |
25 | function.TypeChanged += new EventHandler(function_TypeChanged);
26 | foreach (CArgument arg in function.Arguments)
27 | arg.TypeChanged += new EventHandler(function_TypeChanged);
28 |
29 | this.IsSealed = true;
30 |
31 | // we don't actually want people accessing the default method directly
32 | // we also don't want it to get visited through the type.
33 | // so we don't do this: Members.Add(function.Name, method);
34 | Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(null, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
35 | }
36 |
37 | private void function_TypeChanged(object sender, EventArgs e)
38 | {
39 | UpdateName();
40 | OnTypeChanged();
41 | }
42 |
43 | private void UpdateName()
44 | {
45 | string name = target.TypeSignature;
46 | NameToken = CToken.Identifer(NameToken, name, name);
47 | }
48 |
49 | public override bool canConvertTo(CClass klass)
50 | {
51 | CFunctionType target = klass as CFunctionType;
52 | if (target == null) return base.canConvertTo(klass);
53 |
54 | UpdateName();
55 | target.UpdateName();
56 |
57 | return Name == target.Name;
58 | }
59 |
60 | public static bool PossibleMatch(CFunctionType from, CFunctionType to)
61 | {
62 | if (from.Target.Arguments.Count != to.Target.Arguments.Count)
63 | return false;
64 |
65 | for (int i = 0; i < from.Target.Arguments.Count; i++)
66 | {
67 | if (from.Target.Arguments[i].Direction.Value != to.Target.Arguments[i].Direction.Value)
68 | return false;
69 |
70 | if (from.Target.Arguments[i].Type.Resolved && to.Target.Arguments[i].Type.Resolved
71 | && from.Target.Arguments[i].Type.ActualType != to.Target.Arguments[i].Type.ActualType)
72 | return false;
73 | }
74 |
75 | return true;
76 | }
77 |
78 | public override bool SemanticallyComplete
79 | {
80 | get
81 | {
82 | if (target.SemanticallyComplete && base.SemanticallyComplete)
83 | return true;
84 |
85 | if (!target.Type.Resolved)
86 | return false;
87 | foreach (CArgument arg in target.Arguments)
88 | if (!arg.Type.Resolved)
89 | return false;
90 | if (declarationOnly || target.Statements.SemanticallyComplete)
91 | {
92 | base.SetSemanticallyComplete();
93 | return true;
94 | }
95 |
96 | return false;
97 | }
98 | }
99 | }
100 | }
--------------------------------------------------------------------------------
/AST/CGlobalAccess.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CGlobalAccess : CAccess
7 | {
8 | public CGlobalAccess(CToken tok)
9 | : base(tok, tok)
10 | {
11 | }
12 |
13 | public override void Accept(IVisitor visit)
14 | {
15 | visit.VisitGlobalAccess(this);
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/AST/CHtml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CHtml : CStatement
7 | {
8 | private String htmlString;
9 | private String[] stringArray = null;
10 |
11 | public CHtml(CToken token, String html)
12 | : base(token)
13 | {
14 | htmlString = html;
15 | }
16 |
17 | public string[] HtmlLines
18 | {
19 | get { if (stringArray == null) stringArray = htmlString.Split('\n'); return stringArray; }
20 | set { stringArray = value; }
21 | }
22 |
23 | public override void Accept(IVisitor visitor)
24 | {
25 | visitor.VisitHtml(this);
26 | }
27 |
28 | public String HtmlString
29 | {
30 | get { return htmlString; }
31 | set { htmlString = value; }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/AST/CIf.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CIf : CStatement, INodeParent
7 | {
8 | private CExpression condition;
9 | private CStatementBlock thenStatements = new CStatementBlock();
10 | private CStatementBlock elseStatements = new CStatementBlock();
11 | private CStatementBlock elseIfBlocks = new CStatementBlock();
12 | private bool oneLineFlag;
13 | private bool elseIfFlag;
14 |
15 | public CIf(CToken token, CExpression condition, bool oneLine, bool elseIf)
16 | : base(token)
17 | {
18 | this.condition = condition;
19 | condition.Parent = this;
20 | oneLineFlag = oneLine;
21 | elseIfFlag = elseIf;
22 | }
23 |
24 | public CExpression Condition
25 | {
26 | get { return condition; }
27 | }
28 |
29 | public CStatementBlock ThenStatements
30 | {
31 | get { return thenStatements; }
32 | }
33 |
34 | public CStatementBlock ElseStatements
35 | {
36 | get { return elseStatements; }
37 | }
38 |
39 | public CStatementBlock ElseIfBlocks
40 | {
41 | get { return elseIfBlocks; }
42 | }
43 |
44 | public bool IsOneLine
45 | {
46 | get { return oneLineFlag; }
47 | }
48 |
49 | public bool IsElseIf
50 | {
51 | get { return elseIfFlag; }
52 | }
53 |
54 | public override void Accept(IVisitor visitor)
55 | {
56 | visitor.VisitIf(this);
57 | }
58 |
59 | void INodeParent.Replace(CNode child, CNode newchild)
60 | {
61 | if (child == condition)
62 | condition = (CExpression)newchild;
63 | newchild.Parent = this;
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/AST/CIgnore.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CIgnore : CStatement
7 | {
8 | public CIgnore(CToken token)
9 | : base(token)
10 | {
11 | }
12 |
13 | public override void Accept(IVisitor visitor)
14 | {
15 | visitor.VisitStatement(this);
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/AST/CInterface.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Diagnostics;
5 |
6 | namespace FogCreek.Wasabi.AST
7 | {
8 | [DebuggerDisplay("Name: {RawName}")]
9 | public class CInterface : CClass
10 | {
11 |
12 | List genericParameters = new List();
13 |
14 | public CInterface(CToken tok, CToken name) : base(tok, name.RawValue, name.Value, CTypeRef.Empty) { }
15 |
16 | public List GenericParameters { get { return genericParameters; } }
17 |
18 | public override void Accept(IVisitor visitor)
19 | {
20 | visitor.VisitInterface(this);
21 | }
22 |
23 | public override CMember LookupMember(string k)
24 | {
25 | CMember baseMember = base.LookupMember(k);
26 | if (baseMember == null)
27 | {
28 | foreach (CInterface iface in this.Interfaces)
29 | {
30 | CMember lum = iface.LookupMember(k);
31 | if (lum != null)
32 | return lum;
33 | }
34 | }
35 | return baseMember;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/AST/CLambdaExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CLambdaExpression : CExpression
7 | {
8 | private static int lambdaCount = 0;
9 |
10 | private int lambdaId;
11 | private CLambdaFunction lambdaFunction;
12 | private CFunctionType lambdaType;
13 |
14 | public CLambdaExpression(CToken token)
15 | : base(token)
16 | {
17 | lambdaId = lambdaCount++;
18 | }
19 |
20 | public CLambdaFunction LambdaFunction
21 | {
22 | get { return lambdaFunction; }
23 | }
24 |
25 | public CFunctionType LambdaType
26 | {
27 | get { return lambdaType; }
28 | }
29 |
30 | public override void Accept(IVisitor visitor)
31 | {
32 | visitor.VisitLambdaExpression(this);
33 | }
34 |
35 | public override bool SemanticallyComplete
36 | {
37 | get { return lambdaType.SemanticallyComplete; }
38 | }
39 |
40 | internal CStatementBlock StartInitialize(CFunction containingFunction, CFile containingFile, CTypeRef tref, CArgumentList args)
41 | {
42 | if (lambdaFunction != null)
43 | throw new InvalidOperationException("Lambdas can only be initalized once");
44 |
45 | CClass @class = null;
46 | string extra = "";
47 | if (containingFunction != null)
48 | {
49 | @class = containingFunction.Class;
50 | extra += containingFunction.RawName;
51 | }
52 |
53 | lambdaFunction =
54 | new CLambdaFunction(Token, containingFunction, containingFile, "Lambda_" + extra + "_" + lambdaId, tref, args);
55 | base.LoadType(lambdaType = new CFunctionType(Token, lambdaFunction, false));
56 |
57 | lambdaFunction.Class = @class;
58 |
59 | return lambdaFunction.Statements;
60 | }
61 |
62 | internal void FinishInitialize(CExpression cExpression)
63 | {
64 | CReturn @return = new CReturn(Token);
65 | @return.Expression = cExpression;
66 |
67 | lambdaFunction.Statements.Add(@return);
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/AST/CLambdaFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CLambdaFunction : CFunction
7 | {
8 | private readonly CFunction containingFunction;
9 | private readonly CFile containingFile;
10 | private readonly List externalReferences = new List();
11 |
12 | public CLambdaFunction(CToken token, CFunction containingFunction, CFile containingFile, String name, CTypeRef tref,
13 | CArgumentList args)
14 | : base(token, name, name, TokenTypes.visInternal, FunctionType.Function, args, tref)
15 | {
16 | this.containingFunction = containingFunction;
17 | this.containingFile = containingFile;
18 | if (this.containingFunction != null)
19 | this.containingFunction.Lambdas.Add(this);
20 | else
21 | this.containingFile.Lambdas.Add(this);
22 | CallCount++;
23 | Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(null, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
24 | }
25 |
26 | public CFunction ContainingFunction
27 | {
28 | get { return containingFunction; }
29 | }
30 |
31 | public CFile ContainingFile
32 | {
33 | get { return containingFile; }
34 | }
35 |
36 | ///
37 | /// The list of external references, that are not globals or fields
38 | ///
39 | public List ExternalReferences
40 | {
41 | get { return externalReferences; }
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/AST/CLock.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace FogCreek.Wasabi.AST
6 | {
7 | public class CLock : CStatement, INodeParent
8 | {
9 | private CExpression lockObj;
10 | private CStatementBlock statements = new CStatementBlock();
11 |
12 | public CLock(CToken token, CExpression value)
13 | : base(token)
14 | {
15 | lockObj = value;
16 | value.Parent = this;
17 | }
18 |
19 | public CStatementBlock Statements
20 | {
21 | get { return statements; }
22 | }
23 |
24 | public CExpression Value
25 | {
26 | get { return lockObj; }
27 | }
28 |
29 | public override void Accept(IVisitor visitor)
30 | {
31 | visitor.VisitLock(this);
32 | }
33 |
34 | #region INodeParent Members
35 |
36 | void INodeParent.Replace(CNode child, CNode newchild)
37 | {
38 | if (lockObj == child)
39 | {
40 | lockObj = (CExpression)newchild;
41 | newchild.Parent = this;
42 | }
43 | }
44 |
45 | #endregion
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/AST/CLogic.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CLogic : CBinaryOperator
7 | {
8 | public CLogic(CToken tok, CExpression lhs, CExpression rhs)
9 | : base(tok, lhs, rhs)
10 | {
11 | }
12 |
13 | public override void Accept(IVisitor visit)
14 | {
15 | visit.VisitLogic(this);
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/AST/CMath.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CMath : CBinaryOperator
7 | {
8 | public CMath(CToken tok, CExpression lhs, CExpression rhs)
9 | : base(tok, lhs, rhs)
10 | {
11 | }
12 |
13 | public override void Accept(IVisitor visit)
14 | {
15 | visit.VisitMath(this);
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/AST/CMathUnary.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CMathUnary : CUnaryOperator
7 | {
8 | public CMathUnary(CToken tok, CExpression rhs)
9 | : base(tok, rhs)
10 | {
11 | }
12 |
13 | public override bool IsConstant
14 | {
15 | get
16 | {
17 | return Operand.IsConstant;
18 | }
19 | }
20 |
21 | public override void Accept(IVisitor visit)
22 | {
23 | visit.VisitMathUnary(this);
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/AST/CMember.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | namespace FogCreek.Wasabi.AST
6 | {
7 | public class CMemberDictionary : CNode, IEnumerable>
8 | {
9 | private List> members = new List>();
10 | private Dictionary memberDict = new Dictionary();
11 |
12 | public int Count
13 | {
14 | get { return members.Count; }
15 | }
16 |
17 | public IEnumerable Values
18 | {
19 | get
20 | {
21 | // We iterate over our list of members to preserve order.
22 | foreach (KeyValuePair pair in members)
23 | {
24 | yield return pair.Value;
25 | }
26 | }
27 | }
28 |
29 | public override void Accept(IVisitor visitor)
30 | {
31 | throw new NotImplementedException();
32 | }
33 |
34 | public bool ContainsKey(string name)
35 | {
36 | return memberDict.ContainsKey(name);
37 | }
38 |
39 | public CMember this[string name]
40 | {
41 | get
42 | {
43 | return memberDict[name];
44 | }
45 | set
46 | {
47 | if (memberDict.ContainsKey(name))
48 | {
49 | for (int ix = 0; ix < members.Count; ix++)
50 | {
51 | if (String.CompareOrdinal(members[ix].Key, name) == 0)
52 | {
53 | members[ix] = new KeyValuePair(name, value);
54 | memberDict[name] = value;
55 | return;
56 | }
57 | }
58 | }
59 | else
60 | {
61 | members.Add(new KeyValuePair(name, value));
62 | memberDict[name] = value;
63 | }
64 | }
65 | }
66 |
67 | ///
68 | ///Returns an enumerator that iterates through the collection.
69 | ///
70 | ///
71 | ///
72 | ///A that can be used to iterate through the collection.
73 | ///
74 | ///1
75 | IEnumerator> IEnumerable>.GetEnumerator()
76 | {
77 | return members.GetEnumerator();
78 | }
79 |
80 | ///
81 | ///Returns an enumerator that iterates through a collection.
82 | ///
83 | ///
84 | ///
85 | ///An object that can be used to iterate through the collection.
86 | ///
87 | ///2
88 | public IEnumerator GetEnumerator()
89 | {
90 | return members.GetEnumerator();
91 | }
92 |
93 | public bool TryGetValue(string name, out CMember result)
94 | {
95 | return memberDict.TryGetValue(name, out result);
96 | }
97 |
98 | public void Clear()
99 | {
100 | members.Clear();
101 | memberDict.Clear();
102 | }
103 | }
104 |
105 | public abstract class CMember : CNode, IHasVisibility
106 | {
107 | private readonly String name;
108 | private readonly String memberType;
109 | private readonly CNode[] declared;
110 | private readonly bool isUnionMember;
111 |
112 | public CMember(CToken tok, string name, string memberType, int declaredSize, bool isUnionMember)
113 | : base(tok)
114 | {
115 | this.name = name;
116 | this.memberType = memberType;
117 | declared = new CNode[declaredSize];
118 | this.isUnionMember = isUnionMember;
119 | }
120 |
121 | public abstract TokenTypes Visibility { get; }
122 | public abstract CClass DeclaringClass { get; }
123 |
124 | public string Name
125 | {
126 | get { return name; }
127 | }
128 |
129 | private string rawname = null;
130 | public string RawName
131 | {
132 | get
133 | {
134 | if (rawname != null)
135 | return rawname;
136 |
137 | switch (memberType)
138 | {
139 | case "method":
140 | rawname = ((CMethod)this).Function.RawName;
141 | break;
142 | case "property":
143 | rawname = ((CProperty)this).GetAccessor.RawName;
144 | break;
145 | case "field":
146 | rawname = ((CField)this).Variable.Name.RawValue;
147 | break;
148 | case "const":
149 | rawname = ((CClassConst)this).Constant.Name.RawValue;
150 | break;
151 | case "override":
152 | CMemberOverload cmo = (CMemberOverload)this;
153 | foreach (var x in cmo.Overloads)
154 | {
155 | if (rawname == null)
156 | rawname = x.RawName;
157 | else if (rawname != x.RawName)
158 | throw new NotImplementedException(memberType + " with " + rawname + " and " + x.RawName);
159 | }
160 | break;
161 | default:
162 | throw new InvalidOperationException();
163 | }
164 | return rawname;
165 | }
166 | }
167 |
168 | public string MemberType
169 | {
170 | get { return memberType; }
171 | }
172 |
173 | public override void ClearType()
174 | {
175 | if (declared[0] != null)
176 | declared[0].ClearType();
177 | }
178 |
179 | public override void LoadType(CClass type)
180 | {
181 | if (declared[0] != null)
182 | declared[0].LoadType(type);
183 | }
184 |
185 | public override void LoadType(CTypeRef tref)
186 | {
187 | if (declared[0] != null)
188 | declared[0].LoadType(tref);
189 | }
190 |
191 | public override CTypeRef Type
192 | {
193 | get
194 | {
195 | if (declared[0] == null)
196 | return new CTypeRef(this, (CClass)null);
197 | return declared[0].Type;
198 | }
199 | }
200 |
201 | public CNode[] Declared
202 | {
203 | get { return declared; }
204 | }
205 |
206 | public bool IsUnionMember { get { return isUnionMember; } }
207 |
208 | public override void Accept(IVisitor visitor)
209 | {
210 | foreach (CNode node in declared)
211 | {
212 | if (node != null)
213 | node.Accept(visitor);
214 | }
215 | }
216 |
217 | public override bool SemanticallyComplete
218 | {
219 | get
220 | {
221 | for (int i = 0; i < declared.Length; i++)
222 | {
223 | if (declared[i] != null && !declared[i].SemanticallyComplete)
224 | return false;
225 | }
226 | return true;
227 | }
228 | }
229 |
230 | public override void SetSemanticallyComplete()
231 | {
232 | throw new InvalidOperationException("Class members are dynamically semantically complete");
233 | }
234 |
235 | bool hasExplicit = false;
236 | string strExplicit = "Error In Compiler";
237 | internal bool HasExplicitInterface { get { return hasExplicit; } }
238 | internal string ExplicitInterfaceName
239 | {
240 | get
241 | {
242 | if (hasExplicit)
243 | return strExplicit;
244 | throw new InvalidOperationException(this.name + " does not have an explicit interface.");
245 | }
246 | }
247 |
248 | internal void SetExplicitInterface(string rawIfaceName)
249 | {
250 | hasExplicit = true;
251 | strExplicit = rawIfaceName;
252 | }
253 |
254 | bool isStatic = false;
255 | public bool IsStatic
256 | {
257 | get { return isStatic; }
258 | set { isStatic = value; }
259 | }
260 |
261 | public string VisibilityString
262 | {
263 | get
264 | {
265 | switch (Visibility)
266 | {
267 | default:
268 | case TokenTypes.visPrivate:
269 | return "Private";
270 | case TokenTypes.visProtected:
271 | return "Protected";
272 | case TokenTypes.visPublic:
273 | return "Public";
274 | case TokenTypes.visInternal:
275 | return "Internal";
276 | }
277 | }
278 | }
279 |
280 | public virtual IEnumerable Overloads
281 | {
282 | get
283 | {
284 | return null;
285 | }
286 | }
287 | }
288 | }
--------------------------------------------------------------------------------
/AST/CMemberAccess.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CMemberAccess : CAccess, INodeParent
7 | {
8 | private CAccess _object;
9 | private CMember member;
10 |
11 | public CMemberAccess(CToken tok, CAccess objectSource, CToken item)
12 | : base(tok, item)
13 | {
14 | _object = objectSource;
15 | _object.Parent = this;
16 | _object.IsMemberSource = true;
17 | IsRootAccess = false;
18 | }
19 |
20 | public CAccess MemberSource
21 | {
22 | get { return _object; }
23 | }
24 |
25 | public CMember ReferencedMember
26 | {
27 | get { return member; }
28 | set { member = value; }
29 | }
30 |
31 | public override void Accept(IVisitor visit)
32 | {
33 | visit.VisitMemberAccess(this);
34 | }
35 |
36 | void INodeParent.Replace(CNode child, CNode newchild)
37 | {
38 | if (child == _object)
39 | _object = (CAccess)newchild;
40 | newchild.Parent = this;
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/AST/CMemberOverload.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using FogCreek.Wasabi.AST;
5 |
6 | namespace FogCreek.Wasabi.AST
7 | {
8 | public class CMemberOverload : CMember
9 | {
10 | CClass owner;
11 | List overloads = new List();
12 |
13 | public CMemberOverload(CToken tok, CClass owner, string name)
14 | : base(tok, name, "override", 0, false)
15 | {
16 | this.owner = owner;
17 | }
18 |
19 | public CMemberOverload(CMemberOverload field, bool isUnionMember)
20 | : base(field.Token, field.Name, "override", 0, isUnionMember)
21 | {
22 | this.owner = field.DeclaringClass;
23 | }
24 |
25 | public void Add(CMember member)
26 | {
27 | if (member is CMemberOverload)
28 | {
29 | foreach (CMember m in ((CMemberOverload)member).overloads)
30 | Add(m);
31 | }
32 | else
33 | overloads.Add(member);
34 | }
35 |
36 | public CClass Owner
37 | {
38 | get { return owner; }
39 | }
40 |
41 | public override IEnumerable Overloads
42 | {
43 | get
44 | {
45 | return overloads;
46 | }
47 | }
48 |
49 | public override TokenTypes Visibility
50 | {
51 | get
52 | {
53 | TokenTypes vis = overloads[0].Visibility;
54 | foreach (CMember m in overloads)
55 | if (m.Visibility != vis)
56 | throw new NotImplementedException("Mixed visibility in member overloads");
57 | return vis;
58 | }
59 | }
60 |
61 | public override CClass DeclaringClass
62 | {
63 | get { return owner; }
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/AST/CMemberVariable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CMemberVariable : CDim, IHasVisibility
7 | {
8 | private TokenTypes visibility;
9 |
10 | /// Creates a new instance of CMemberVariable
11 | // ppub = 0, priv =1 as defined in token types interface
12 | public CMemberVariable(CToken token, TokenTypes visibility)
13 | : base(token)
14 | {
15 | this.visibility = visibility;
16 | }
17 |
18 | public TokenTypes Visibility
19 | {
20 | get { return visibility; }
21 | internal set { visibility = value; }
22 | }
23 |
24 | public override void Accept(IVisitor visitor)
25 | {
26 | visitor.VisitMemberVariable(this);
27 | }
28 |
29 | #region IHasVisibility Members
30 |
31 | public CClass DeclaringClass
32 | {
33 | get { return this.Variables[0].ContainingClass; }
34 | }
35 |
36 | bool isStatic = false;
37 | public bool IsStatic
38 | {
39 | get { return isStatic; }
40 | set { isStatic = value; }
41 | }
42 |
43 | #endregion
44 | }
45 | }
--------------------------------------------------------------------------------
/AST/CMethod.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CMethod : CMember
7 | {
8 | private CFunction function;
9 |
10 | public CMethod(CFunction func)
11 | : base(func.Token, func.Name, "method", 1, false)
12 | {
13 | Declared[0] = func;
14 | function = func;
15 | }
16 |
17 | public CMethod(CMethod method, bool isUnionMember)
18 | : base(method.Token, method.Name, "method", 1, isUnionMember)
19 | {
20 | Declared[0] = function = method.function;
21 | }
22 |
23 | public CFunction Function
24 | {
25 | get { return function; }
26 | }
27 |
28 | ///
29 | /// Function is a reserved word in Wasabi, so we add an alias "FunctionObject".
30 | ///
31 | public CFunction FunctionObject
32 | {
33 | get { return function; }
34 | }
35 |
36 | public override TokenTypes Visibility
37 | {
38 | get { return function.Visibility; }
39 | }
40 |
41 | public override CClass DeclaringClass
42 | {
43 | get { return function.DeclaringClass; }
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/AST/CNew.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CNew : CAccess
7 | {
8 | private CToken classname;
9 | private CParameters @params;
10 |
11 | public CNew(CToken tok, CToken classname, CParameters @params)
12 | : base(tok, classname)
13 | {
14 | this.classname = classname;
15 | this.@params = @params;
16 | this.@params.Parent = this;
17 | }
18 |
19 | public CParameters Parameters
20 | {
21 | get { return @params; }
22 | }
23 |
24 | public CToken ClassName
25 | {
26 | get { return classname; }
27 | }
28 |
29 | public override void Accept(IVisitor visit)
30 | {
31 | visit.VisitNew(this);
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/AST/CNewline.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CNewline : CStatement
7 | {
8 | public CNewline(CToken token)
9 | : base(token)
10 | {
11 | }
12 |
13 | public override void Accept(IVisitor visitor)
14 | {
15 | visitor.VisitStatement(this);
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/AST/CNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | namespace FogCreek.Wasabi.AST
6 | {
7 | public interface INodeParent
8 | {
9 | void Replace(CNode child, CNode newchild);
10 | }
11 |
12 | public enum NodeStateMode
13 | {
14 | Initial,
15 | Server,
16 | Client,
17 | MaxStateValue
18 | }
19 |
20 | public abstract class CNode
21 | {
22 | private static List allNodes = new List();
23 | private CToken token;
24 | private CTypeRef type;
25 | private INodeParent parent;
26 | private bool _semanticallyComplete = false;
27 | public event EventHandler TypeChanged;
28 |
29 | protected CNode(CToken token)
30 | {
31 | type = new CTypeRef(this);
32 | this.token = token;
33 | lock (allNodes) allNodes.Add(this);
34 | }
35 |
36 | protected CNode()
37 | {
38 | type = new CTypeRef(this);
39 | token = null;
40 | lock (allNodes) allNodes.Add(this);
41 | }
42 |
43 | public virtual int LineNumber
44 | {
45 | get
46 | {
47 | if (token != null)
48 | return token.LineNumber;
49 | return 0;
50 | }
51 | }
52 |
53 | public virtual bool SemanticallyComplete
54 | {
55 | get { return _semanticallyComplete; }
56 | }
57 |
58 | public CToken Token
59 | {
60 | get { return token; }
61 | }
62 |
63 | public virtual CTypeRef Type
64 | {
65 | get { return type; }
66 | }
67 |
68 | public virtual void ClearType()
69 | {
70 | type = new CTypeRef(this);
71 | }
72 |
73 | public virtual void LoadType(CClass type)
74 | {
75 | this.type.InternalLoad(type);
76 | }
77 |
78 | public virtual void LoadType(CTypeRef tref)
79 | {
80 | type.InternalLoad(tref);
81 | }
82 |
83 | internal void DoTypeChanged()
84 | {
85 | OnTypeChanged();
86 | }
87 |
88 | protected void OnTypeChanged()
89 | {
90 | if (TypeChanged != null) TypeChanged(this, new EventArgs());
91 | }
92 |
93 | public INodeParent Parent
94 | {
95 | get { return parent; }
96 | protected internal set { parent = value; }
97 | }
98 |
99 | public virtual void SetSemanticallyComplete()
100 | {
101 | if (!type.Resolved)
102 | throw new InvalidOperationException("Type must be resolved before calling SetSemanticallyComplete()");
103 | _semanticallyComplete = true;
104 | }
105 |
106 | public abstract void Accept(IVisitor visitor);
107 |
108 | internal static void ClearSemanticallyCompleteOnAllNodes()
109 | {
110 | foreach (CNode node in allNodes)
111 | node._semanticallyComplete = false;
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/AST/CNot.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CNot : CUnaryOperator
7 | {
8 | public CNot(CToken tok, CExpression rhs)
9 | : base(tok, rhs)
10 | {
11 | base.LoadType(BuiltIns.Boolean);
12 | }
13 |
14 | public override void Accept(IVisitor visit)
15 | {
16 | visit.VisitNot(this);
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/AST/COnError.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class COnError : CStatement
7 | {
8 | private CToken action;
9 |
10 | public COnError(CToken tok, CToken action)
11 | : base(tok)
12 | {
13 | this.action = action;
14 | }
15 |
16 | public override void Accept(IVisitor visit)
17 | {
18 | visit.VisitOnError(this);
19 | }
20 |
21 | public CToken Action
22 | {
23 | get { return action; }
24 | set { action = value; }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/AST/COnExit.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace FogCreek.Wasabi.AST
6 | {
7 | public class COnExit : COnError
8 | {
9 | CStatement statement;
10 |
11 | public COnExit(CToken tok, CToken action, CStatement statement)
12 | : base(tok, action)
13 | {
14 | this.statement = statement;
15 | }
16 |
17 | public override void Accept(IVisitor visit)
18 | {
19 | visit.VisitOnExit(this);
20 | }
21 |
22 | public CStatement Statement { get { return statement; } }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/AST/COption.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class COption : CStatement
7 | {
8 | private CToken name;
9 | private CToken param;
10 | private CFile file;
11 |
12 | public COption(CToken tok, CToken name, CToken param)
13 | : base(tok)
14 | {
15 | this.name = name;
16 | this.param = param;
17 | }
18 |
19 | public CToken Name
20 | {
21 | get { return name; }
22 | }
23 |
24 | public CToken Parameter
25 | {
26 | get { return param; }
27 | }
28 |
29 | public CFile File
30 | {
31 | get { return file; }
32 | set { file = value; }
33 | }
34 |
35 | public override void Accept(IVisitor visitor)
36 | {
37 | visitor.VisitOption(this);
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/AST/COptionalByRef.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace FogCreek.Wasabi.AST
6 | {
7 | public class COptionalByRef : CExpression
8 | {
9 | public COptionalByRef(CToken tok)
10 | : base(tok)
11 | {
12 | this.IsPassedByRef = true;
13 | }
14 |
15 | public override void Accept(IVisitor visitor)
16 | {
17 | visitor.VisitOptionalByRef(this);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/AST/CParameters.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | namespace FogCreek.Wasabi.AST
6 | {
7 | public class CParameters : INodeParent
8 | {
9 | public class ParameterList : IEnumerable
10 | {
11 | private readonly INodeParent parent;
12 | private List items = new List();
13 |
14 | public ParameterList(INodeParent parent)
15 | {
16 | this.parent = parent;
17 | }
18 |
19 | public ParameterList(INodeParent parent, ParameterList source)
20 | {
21 | this.parent = parent;
22 | items.AddRange(source.items);
23 | }
24 |
25 | public void Add(CNode parameter)
26 | {
27 | if (parameter != null)
28 | parameter.Parent = parent;
29 | items.Add(parameter);
30 | }
31 |
32 | public void RemoveAt(int ix)
33 | {
34 | items.RemoveAt(ix);
35 | }
36 |
37 | public int Count
38 | {
39 | get { return items.Count; }
40 | }
41 |
42 | public CNode this[int ix]
43 | {
44 | get { return items[ix]; }
45 | set
46 | {
47 | items[ix] = value;
48 | value.Parent = parent;
49 | }
50 | }
51 |
52 | public void Replace(CNode child, CNode newchild)
53 | {
54 | for (int ix = 0; ix < items.Count; ix++)
55 | {
56 | if (items[ix] == child)
57 | {
58 | items[ix] = newchild;
59 | newchild.Parent = parent;
60 | }
61 | }
62 | }
63 |
64 | internal void UpdateParents()
65 | {
66 | foreach (CNode node in items)
67 | if (node != null)
68 | node.Parent = parent;
69 | }
70 |
71 | #region IEnumerable Members
72 |
73 | IEnumerator IEnumerable.GetEnumerator()
74 | {
75 | return items.GetEnumerator();
76 | }
77 |
78 | #endregion
79 |
80 | #region IEnumerable Members
81 |
82 | IEnumerator IEnumerable.GetEnumerator()
83 | {
84 | return items.GetEnumerator();
85 | }
86 |
87 | #endregion
88 | }
89 |
90 | public class NamedParameterList : object, IEnumerable>, INodeParent
91 | {
92 | CParameters parent;
93 | int count = 0;
94 | KeyValuePair[] items;
95 |
96 | public NamedParameterList(CParameters parent, int size)
97 | {
98 | this.parent = parent;
99 | items = new KeyValuePair[size * 2];
100 | count = 0;
101 | }
102 |
103 | public NamedParameterList(CParameters parent)
104 | : this(parent, 16)
105 | {
106 | }
107 |
108 | public NamedParameterList(CParameters parent, NamedParameterList src)
109 | : this(parent, src.count)
110 | {
111 | Array.Copy(src.items, items, src.count);
112 | count = src.count;
113 | }
114 |
115 | public CNode this[string key]
116 | {
117 | get
118 | {
119 | for (int i = 0; i < count; i++)
120 | {
121 | if (items[i].Key == key) return items[i].Value;
122 | }
123 | throw new ArgumentOutOfRangeException("key");
124 | }
125 | }
126 |
127 | public KeyValuePair this[int ix]
128 | {
129 | get { return items[ix]; }
130 | }
131 |
132 | public int Count
133 | {
134 | get { return count; }
135 | }
136 |
137 | #region INodeParent Members
138 |
139 | public void Replace(CNode child, CNode newchild)
140 | {
141 | for (int i = 0; i < count; i++)
142 | {
143 | if (items[i].Value == child)
144 | {
145 | items[i] = new KeyValuePair(items[i].Key, newchild);
146 | newchild.Parent = parent;
147 | }
148 | }
149 | }
150 |
151 | #endregion
152 |
153 | #region IEnumerable> Members
154 |
155 | public IEnumerator> GetEnumerator()
156 | {
157 | for (int i = 0; i < count; i++)
158 | {
159 | yield return items[i];
160 | }
161 | }
162 |
163 | #endregion
164 |
165 | #region IEnumerable Members
166 |
167 | IEnumerator IEnumerable.GetEnumerator()
168 | {
169 | for (int i = 0; i < count; i++)
170 | {
171 | yield return items[i];
172 | }
173 | }
174 |
175 | #endregion
176 |
177 | internal bool ContainsKey(string p)
178 | {
179 | for (int i = 0; i < count; i++)
180 | {
181 | if (items[i].Key == p) return true;
182 | }
183 | return false;
184 | }
185 |
186 | internal void Add(string p, CExpression cExpression)
187 | {
188 | if (items.Length == count)
189 | Array.Resize(ref items, items.Length * 2);
190 | items[count++] = new KeyValuePair(p, cExpression);
191 | cExpression.Parent = parent;
192 | }
193 | }
194 |
195 | private ParameterList unnamedParams;
196 | private NamedParameterList namedParams;
197 | private bool _semanticallyComplete = false;
198 | private CNode parent;
199 |
200 | public CParameters()
201 | {
202 | namedParams = new NamedParameterList(this);
203 | unnamedParams = new ParameterList(this);
204 | }
205 |
206 | public CParameters(CParameters @params)
207 | {
208 | parent = @params.parent;
209 | unnamedParams = new ParameterList(this, @params.unnamedParams);
210 | namedParams = new NamedParameterList(this, @params.namedParams);
211 | }
212 |
213 | public CParameters(params CExpression[] exprs)
214 | : this()
215 | {
216 | foreach (CExpression node in exprs)
217 | {
218 | unnamedParams.Add(node);
219 | }
220 | }
221 |
222 | public void Accept(IVisitor visit)
223 | {
224 | visit.VisitParameters(this);
225 | }
226 |
227 | internal List GetDistinctNodes()
228 | {
229 | List list = new List();
230 | foreach (CNode node in unnamedParams)
231 | if (node != null && !list.Contains(node))
232 | list.Add(node);
233 | foreach (KeyValuePair pair in namedParams)
234 | if (pair.Value != null && !list.Contains(pair.Value))
235 | list.Add(pair.Value);
236 | return list;
237 | }
238 |
239 | public bool SemanticallyComplete
240 | {
241 | get { return _semanticallyComplete; }
242 | }
243 |
244 | public ParameterList Unnamed
245 | {
246 | get { return unnamedParams; }
247 | }
248 |
249 | public NamedParameterList Named
250 | {
251 | get { return namedParams; }
252 | }
253 |
254 | public CNode this[int ix]
255 | {
256 | get { return unnamedParams[ix]; }
257 | }
258 |
259 | public CNode Parent
260 | {
261 | get { return parent; }
262 | set { parent = value; }
263 | }
264 |
265 | public void setSemanticallyComplete()
266 | {
267 | _semanticallyComplete = true;
268 | }
269 |
270 | public void resetSemanticallyComplete()
271 | {
272 | _semanticallyComplete = false;
273 | }
274 |
275 | public void Replace(CNode child, CNode newchild)
276 | {
277 | namedParams.Replace(child, newchild);
278 | unnamedParams.Replace(child, newchild);
279 | }
280 | }
281 | }
--------------------------------------------------------------------------------
/AST/CParenExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CParenExpression : CExpression, INodeParent
7 | {
8 | private CExpression inner;
9 |
10 | public CParenExpression(CToken tok, CExpression inner)
11 | : base(tok)
12 | {
13 | this.inner = inner;
14 | inner.Parent = this;
15 | }
16 |
17 | public CExpression InnerExpression
18 | {
19 | get { return inner; }
20 | }
21 |
22 | public override bool IsConstant
23 | {
24 | get
25 | {
26 | return inner.IsConstant;
27 | }
28 | }
29 |
30 | public override void Accept(IVisitor visit)
31 | {
32 | visit.VisitParenExpression(this);
33 | }
34 |
35 | void INodeParent.Replace(CNode child, CNode newchild)
36 | {
37 | if (inner == child)
38 | inner = (CExpression)newchild;
39 | newchild.Parent = this;
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/AST/CPictureOfExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CPictureOfExpression : CExpression, INodeParent
7 | {
8 | private CAccess access;
9 |
10 | public CPictureOfExpression(CToken tok, CAccess access)
11 | : base(tok)
12 | {
13 | this.access = access;
14 | this.access.Parent = this;
15 | }
16 |
17 | public override void Accept(IVisitor visitor)
18 | {
19 | visitor.VisitPictureOf(this);
20 | }
21 |
22 | public CAccess AccessTarget
23 | {
24 | get { return access; }
25 | set { access = value; }
26 | }
27 |
28 | #region INodeParent Members
29 |
30 | void INodeParent.Replace(CNode child, CNode newchild)
31 | {
32 | if (child == access)
33 | {
34 | access = (CAccess)newchild;
35 | newchild.Parent = this;
36 | }
37 | }
38 |
39 | #endregion
40 | }
41 | }
--------------------------------------------------------------------------------
/AST/CProperty.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CProperty : CMember
7 | {
8 | public const int ixGet = 0;
9 | public const int ixSet = 1;
10 |
11 | private CFunction m_get;
12 | private CFunction m_set;
13 |
14 | public CProperty(CToken token, string name)
15 | : base(token, name, "property", 3, false)
16 | {
17 | }
18 |
19 | public CProperty(CProperty property, bool isUnionMember)
20 | : base(property.Token, property.Name, "property", 3, isUnionMember)
21 | {
22 | Declared[ixGet] = m_get = property.m_get;
23 | Declared[ixSet] = m_set = property.m_set;
24 | }
25 |
26 | public CFunction GetAccessor
27 | {
28 | get { return m_get; }
29 | set
30 | {
31 | if (m_get != null)
32 | throw new InvalidCastException();
33 | m_get = value;
34 | Declared[ixGet] = value;
35 | }
36 | }
37 |
38 | public CFunction SetAccessor
39 | {
40 | get { return m_set; }
41 | set
42 | {
43 | if (m_set != null)
44 | throw new InvalidCastException();
45 | m_set = value;
46 | Declared[ixSet] = value;
47 | }
48 | }
49 |
50 | public override TokenTypes Visibility
51 | {
52 | get { return (GetAccessor ?? SetAccessor).Visibility; }
53 | }
54 |
55 | public override CClass DeclaringClass
56 | {
57 | get { return (GetAccessor ?? SetAccessor).DeclaringClass; }
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/AST/CReDim.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CReDim : CDim
7 | {
8 | private bool bPreserve;
9 |
10 | public CReDim(CToken token, bool preserve)
11 | : base(token)
12 | {
13 | bPreserve = preserve;
14 | }
15 |
16 | public bool PreserveArrayContents
17 | {
18 | get { return bPreserve; }
19 | }
20 |
21 | public override void Accept(IVisitor visitor)
22 | {
23 | visitor.VisitReDim(this);
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/AST/CReturn.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CReturn : CStatement, INodeParent
7 | {
8 | private CExpression expression;
9 |
10 | public CReturn(CToken token)
11 | : base(token) {}
12 |
13 | public CExpression Expression
14 | {
15 | get { return expression; }
16 | set
17 | {
18 | this.expression = value;
19 | value.Parent = this;
20 | }
21 | }
22 |
23 | public void Replace(CNode child, CNode newchild)
24 | {
25 | if (child == expression)
26 | Expression = (CExpression)newchild;
27 | }
28 |
29 | public override void Accept(IVisitor visitor)
30 | {
31 | visitor.VisitReturn(this);
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/AST/CScope.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CScope
7 | {
8 | public CScope Parent
9 | {
10 | get { return parent; }
11 | set { parent = value; }
12 | }
13 |
14 | private Dictionary funcs = new Dictionary(StringComparer.Ordinal);
15 | private Dictionary nodes = new Dictionary(StringComparer.Ordinal);
16 | private CScope parent;
17 |
18 | public CScope()
19 | {
20 | }
21 |
22 | public CScope(CScope scope)
23 | {
24 | foreach (KeyValuePair pair in scope.funcs)
25 | {
26 | funcs[pair.Key] = pair.Value;
27 | }
28 | foreach (KeyValuePair pair in scope.nodes)
29 | {
30 | nodes[pair.Key] = pair.Value;
31 | }
32 | if (scope.parent != null)
33 | throw new InvalidOperationException("Cannot clone a parented scope");
34 | }
35 |
36 | internal void add(String name, CNode node)
37 | {
38 | // TODO add previous existance check
39 | nodes[name] = node;
40 | }
41 |
42 | public void add(CConst var)
43 | {
44 | add(var.Name.Value, var);
45 | }
46 |
47 | public void add(CVariableBase var)
48 | {
49 | add(var.Name.Value, var);
50 | }
51 |
52 | public void add(CClass type)
53 | {
54 | add(type.Name, type);
55 | }
56 |
57 | public void add(CMember member)
58 | {
59 | if (member.MemberType == "field")
60 | add(member.Name, member.Declared[0]);
61 | else if (member.MemberType == "const")
62 | add(member.Name, member.Declared[0]);
63 | else
64 | funcs[member.Name] = member;
65 | }
66 |
67 | public void add(CFunction func)
68 | {
69 | if (func.Class == null)
70 | {
71 | funcs[func.Name] = func;
72 | funcs[func.FunctionAlias.ToLower()] = func;
73 | }
74 | switch (func.FunctionType)
75 | {
76 | case CFunction.vbPropertySet:
77 | case CFunction.vbSub:
78 | break;
79 |
80 | case CFunction.vbPropertyGet:
81 | case CFunction.vbFunction:
82 | default:
83 | func.scope.add(func.Name, func);
84 | break;
85 | }
86 | }
87 |
88 | public bool declared(String name)
89 | {
90 | if (local(name))
91 | return true;
92 | if (parent != null)
93 | return parent.declared(name);
94 | return false;
95 | }
96 |
97 | public bool declaredFunction(String name)
98 | {
99 | if (localFunction(name))
100 | return true;
101 | if (parent != null)
102 | return parent.declaredFunction(name);
103 | return false;
104 | }
105 |
106 | public bool local(String name)
107 | {
108 | return nodes.ContainsKey(name);
109 | }
110 |
111 | public bool localFunction(String name)
112 | {
113 | return funcs.ContainsKey(name);
114 | }
115 |
116 | public void setNode(String name, CNode node)
117 | {
118 | if (nodes.ContainsKey(name))
119 | nodes[name] = node;
120 | else
121 | parent.setNode(name, node);
122 | }
123 |
124 | public CNode getNode(String name)
125 | {
126 | CNode nod;
127 | if (!nodes.TryGetValue(name, out nod))
128 | return parent.getNode(name);
129 | return nod;
130 | }
131 |
132 | public CNode getFunction(String name)
133 | {
134 | CNode val;
135 | if (!funcs.TryGetValue(name, out val))
136 | return parent.getFunction(name);
137 | return val;
138 | }
139 |
140 | internal void Clear()
141 | {
142 | funcs.Clear();
143 | nodes.Clear();
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/AST/CSelect.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | // the class for the switch(select) statement
7 | public class CSelect : CStatement, INodeParent
8 | {
9 | private CExpression pivot; // this is the variable that it swings on
10 | private CStatementBlock cases; // this will be a vector of case objects
11 |
12 | public CSelect(CToken token, CExpression pivot)
13 | : base(token)
14 | {
15 | cases = new CStatementBlock();
16 | this.pivot = pivot;
17 | pivot.Parent = this;
18 | }
19 |
20 | public CExpression Pivot
21 | {
22 | get { return pivot; }
23 | }
24 |
25 | public CStatementBlock Cases
26 | {
27 | get { return cases; }
28 | }
29 |
30 | public override void Accept(IVisitor visitor)
31 | {
32 | visitor.VisitSelect(this);
33 | }
34 |
35 | void INodeParent.Replace(CNode child, CNode newchild)
36 | {
37 | if (child == pivot)
38 | pivot = (CExpression)newchild;
39 | newchild.Parent = this;
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/AST/CSpecialEqual.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | // the CSpecialEqual class is for this situation <%=something%> which turns into <% Response.Write something %>
7 | public class CSpecialEqual : CStatement, INodeParent
8 | {
9 | private CExpression expr;
10 |
11 | public CSpecialEqual(CToken token, CExpression value)
12 | : base(token)
13 | {
14 | expr = value;
15 | expr.Parent = this;
16 | }
17 |
18 | public CExpression Value
19 | {
20 | get { if (expr.Parent != this) throw new DataMisalignedException(); return expr; }
21 | }
22 |
23 | public override void Accept(IVisitor visitor)
24 | {
25 | visitor.VisitSpecialEqual(this);
26 | }
27 |
28 | void INodeParent.Replace(CNode child, CNode newchild)
29 | {
30 | if (child == expr)
31 | expr = (CExpression)newchild;
32 | newchild.Parent = this;
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/AST/CStatement.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | // all of the other classes which handle the different kinds of statements in
7 | // the vbs language all inherit from this class
8 | public abstract class CStatement : CNode
9 | {
10 | private bool hasInlineComment = false;
11 |
12 | protected internal CStatement(CToken token)
13 | : base(token)
14 | {
15 | }
16 |
17 | public bool HasInlineComment
18 | {
19 | get { return hasInlineComment; }
20 | set { hasInlineComment = value; }
21 | }
22 |
23 | public abstract override void Accept(IVisitor visitor);
24 | }
25 | }
--------------------------------------------------------------------------------
/AST/CStatementBlock.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | namespace FogCreek.Wasabi.AST
6 | {
7 | public class CStatementBlock : CNode, IEnumerable, INodeParent
8 | {
9 | private List m_statements = new List();
10 | private bool suppressIndent = false;
11 |
12 | public CStatementBlock()
13 | {
14 | }
15 |
16 | public CStatementBlock(CToken tok, bool suppressIndent) : base(tok)
17 | {
18 | this.suppressIndent = suppressIndent;
19 | }
20 |
21 | public void Add(CNode node)
22 | {
23 | m_statements.Add(node);
24 | node.Parent = this;
25 | }
26 |
27 | public int Count
28 | {
29 | get { return m_statements.Count; }
30 | }
31 |
32 | public int IndexOf(CNode node)
33 | {
34 | if (node is CVariable)
35 | return IndexOf((CVariable)node);
36 | return m_statements.IndexOf(node);
37 | }
38 |
39 | private int IndexOf(CVariable var)
40 | {
41 | int ix = m_statements.IndexOf(var);
42 | if (ix >= 0)
43 | return ix;
44 |
45 | for (ix = 0; ix < m_statements.Count; ix++)
46 | {
47 | CNode n = m_statements[ix];
48 | if (n is CMemberVariable)
49 | if (((CMemberVariable)n).Variables.Contains(var))
50 | return ix;
51 | }
52 |
53 | return -1;
54 | }
55 |
56 | public CNode this[int ix]
57 | {
58 | get { return m_statements[ix]; }
59 | }
60 |
61 | public override void Accept(IVisitor visitor)
62 | {
63 | visitor.VisitBlock(this);
64 | }
65 |
66 | void INodeParent.Replace(CNode child, CNode newchild)
67 | {
68 | for (int i = 0; i < Count; i++)
69 | {
70 | if (this[i] == child)
71 | m_statements[i] = newchild;
72 | }
73 | newchild.Parent = this;
74 | }
75 |
76 | public bool SuppressIndent
77 | {
78 | get { return suppressIndent; }
79 | }
80 |
81 | IEnumerator IEnumerable.GetEnumerator()
82 | {
83 | return m_statements.GetEnumerator();
84 | }
85 |
86 | ///
87 | ///Returns an enumerator that iterates through the collection.
88 | ///
89 | ///
90 | ///
91 | ///A that can be used to iterate through the collection.
92 | ///
93 | ///1
94 | IEnumerator IEnumerable.GetEnumerator()
95 | {
96 | return m_statements.GetEnumerator();
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/AST/CTernary.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CTernary : CExpression, INodeParent
7 | {
8 | private CExpression cond, lhs, rhs;
9 |
10 | public CTernary(CToken tok, CExpression cond, CExpression lhs, CExpression rhs)
11 | : base(tok)
12 | {
13 | this.cond = cond;
14 | this.lhs = lhs;
15 | this.rhs = rhs;
16 |
17 | cond.Parent = this;
18 | lhs.Parent = this;
19 | rhs.Parent = this;
20 | }
21 |
22 | public override bool IsConstant
23 | {
24 | get
25 | {
26 | return cond.IsConstant && lhs.IsConstant && rhs.IsConstant;
27 | }
28 | }
29 |
30 | public CExpression Cond
31 | {
32 | get { return cond; }
33 | }
34 |
35 | public CExpression Left
36 | {
37 | get { return lhs; }
38 | }
39 |
40 | public CExpression Right
41 | {
42 | get { return rhs; }
43 | }
44 |
45 | void INodeParent.Replace(CNode child, CNode newchild)
46 | {
47 | if (cond == child)
48 | cond = (CExpression)newchild;
49 | if (lhs == child)
50 | lhs = (CExpression)newchild;
51 | if (rhs == child)
52 | rhs = (CExpression)newchild;
53 | newchild.Parent = this;
54 | }
55 |
56 | public override void Accept(IVisitor visit)
57 | {
58 | visit.VisitTernary(this);
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/AST/CThisAccess.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CThisAccess : CAccess
7 | {
8 | public CThisAccess(CToken tok)
9 | : base(tok, tok)
10 | {
11 | }
12 |
13 | public override void Accept(IVisitor visit)
14 | {
15 | visit.VisitThisAccess(this);
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/AST/CThrow.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace FogCreek.Wasabi.AST
6 | {
7 | public class CThrow : CStatement, INodeParent
8 | {
9 | CExpression expression;
10 |
11 | public CExpression Expression
12 | {
13 | get { return expression; }
14 | set
15 | {
16 | this.expression = value;
17 | value.Parent = this;
18 | }
19 | }
20 |
21 | ///
22 | /// Create a new Throw statement
23 | ///
24 | /// The token defining the Throw
25 | /// The expression, if any, being thrown (may be null)
26 | public CThrow(CToken token)
27 | : base(token) { }
28 |
29 | public void Replace(CNode child, CNode newchild)
30 | {
31 | if (child == expression)
32 | Expression = (CExpression)newchild;
33 | }
34 |
35 | public override void Accept(IVisitor visitor)
36 | {
37 | visitor.VisitThrow(this);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/AST/CToken.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 |
5 | namespace FogCreek.Wasabi.AST
6 | {
7 | [DebuggerDisplay("Location: {Filename}:{LineNumber}, Value: {Value}")]
8 | public class CToken : Object
9 | {
10 | private String filename;
11 | private int line;
12 | private int offset;
13 | private string fullLine;
14 | private TokenTypes type;
15 | private String m_value;
16 | private String rawvalue;
17 | private bool spacebefore;
18 | private int ix = -1;
19 | public Object AdditionalInfo;
20 |
21 | public CToken(string filename, int line, int offset, string fullLine, TokenTypes typ, string val, string rawval, bool hasspacebefore)
22 | {
23 | this.filename = filename;
24 | this.line = line;
25 | this.offset = offset;
26 | this.fullLine = fullLine;
27 | type = typ;
28 | m_value = val;
29 | rawvalue = rawval;
30 | spacebefore = hasspacebefore;
31 | }
32 |
33 | public CToken(String filename, TokenTypes typ, String val)
34 | : this(filename, 0, 0, "", typ, val, val, false)
35 | {
36 | }
37 |
38 | public CToken()
39 | {
40 | type = (TokenTypes)(-1);
41 | m_value = "";
42 | }
43 |
44 | private readonly static CToken Empty = new CToken();
45 |
46 | public static CToken Identifer(CToken @src, String ident)
47 | {
48 | if (src == null) src = Empty;
49 | return new CToken(src.filename, src.line, src.offset, src.fullLine, TokenTypes.identifier, ident.ToLower(), ident, true);
50 | }
51 |
52 | public static CToken Identifer(CToken @src, String ident, String rawIdent)
53 | {
54 | if (src == null) src = Empty;
55 | return new CToken(src.filename, src.line, src.offset, src.fullLine, TokenTypes.identifier, ident, rawIdent, true);
56 | }
57 |
58 | public static CToken Keyword(CToken @src, String keyword)
59 | {
60 | if (src == null) src = Empty;
61 | return new CToken(src.filename, src.line, src.offset, src.fullLine, TokenTypes.keyword, keyword.ToLower(), keyword, true);
62 | }
63 |
64 | internal static CToken String(CToken @src, string alias)
65 | {
66 | if (src == null) src = Empty;
67 | return new CToken(src.filename, src.line, src.offset, src.fullLine, TokenTypes.str, alias, alias, true);
68 | }
69 |
70 | public string Filename
71 | {
72 | get { return filename; }
73 | }
74 |
75 | public int LineNumber
76 | {
77 | get { return line; }
78 | }
79 |
80 | public int ByteOffset
81 | {
82 | get { return offset; }
83 | }
84 |
85 | public string FullLine
86 | {
87 | get { return fullLine; }
88 | }
89 |
90 | public TokenTypes TokenType
91 | {
92 | get { return type; }
93 | }
94 |
95 | public string Value
96 | {
97 | get { return m_value; }
98 | }
99 |
100 | public string RawValue
101 | {
102 | get
103 | {
104 | if (rawvalue == null) return m_value;
105 | return rawvalue;
106 | }
107 | }
108 |
109 | public bool HasSpaceBefore
110 | {
111 | get { return spacebefore; }
112 | }
113 |
114 | public int Index
115 | {
116 | get { return ix; }
117 | set { ix = value; }
118 | }
119 |
120 | public String ToDebugString()
121 | {
122 | return string.Format("Location: {0}:{1}, Value: {2}", Filename, LineNumber, Value);
123 | }
124 |
125 | public override String ToString()
126 | {
127 | return m_value;
128 | }
129 | }
130 | }
--------------------------------------------------------------------------------
/AST/CTry.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace FogCreek.Wasabi.AST
6 | {
7 | public class CTry : CStatement
8 | {
9 | CStatementBlock statements = new CStatementBlock();
10 | CStatementBlock catchBlocks = new CStatementBlock();
11 | CFinally finallyBlock;
12 |
13 | public CStatementBlock Statements
14 | {
15 | get { return statements; }
16 | }
17 |
18 | public CStatementBlock CatchBlocks
19 | {
20 | get { return catchBlocks; }
21 | }
22 |
23 | public CFinally FinallyBlock
24 | {
25 | get { return finallyBlock; }
26 | set { finallyBlock = value; }
27 | }
28 |
29 | ///
30 | /// Create a new Try-Catch-Finally block.
31 | ///
32 | /// The token defining the Try
33 | public CTry(CToken token)
34 | : base(token) { }
35 |
36 | public override void Accept(IVisitor visitor)
37 | {
38 | visitor.VisitTry(this);
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/AST/CTypeRef.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 |
5 | namespace FogCreek.Wasabi.AST
6 | {
7 | [DebuggerDisplay("TypeName: {TypeName}, ActualType: {ActualType}")]
8 | public struct CTypeRef
9 | {
10 | private readonly CNode owner;
11 | private CToken name;
12 | private CClass type;
13 |
14 | public static readonly CTypeRef Empty = new CTypeRef(null);
15 |
16 | public CTypeRef(CNode owner)
17 | {
18 | this.owner = owner;
19 | name = null;
20 | type = null;
21 | }
22 |
23 | public CTypeRef(CNode owner, CClass type)
24 | : this(owner)
25 | {
26 | InternalLoad(type);
27 | }
28 |
29 | public CTypeRef(CNode owner, CToken name)
30 | : this(owner)
31 | {
32 | InternalLoad(name);
33 | }
34 |
35 | [Obsolete("Only used by generators")]
36 | public CTypeRef(CNode owner, string name) : this(owner)
37 | {
38 | InternalLoad(CToken.Identifer(null, name));
39 | }
40 |
41 | public CTypeRef(CNode owner, CTypeRef tref)
42 | : this(owner)
43 | {
44 | InternalLoad(tref);
45 | }
46 |
47 | public CNode Owner
48 | {
49 | get { return owner; }
50 | }
51 |
52 | internal void InternalLoad(CTypeRef tref)
53 | {
54 | TypeName = tref.name;
55 | ActualType = tref.type;
56 | }
57 |
58 | internal void InternalLoad(CClass type)
59 | {
60 | ActualType = type;
61 | }
62 |
63 | internal void InternalLoad(CToken name)
64 | {
65 | TypeName = name;
66 | ActualType = null;
67 | }
68 |
69 | public CToken TypeName
70 | {
71 | get
72 | {
73 | if (Resolved) return type.NameToken;
74 | return name;
75 | }
76 | private set { name = value; }
77 | }
78 |
79 | public string RawName
80 | {
81 | get { return type.RawName; }
82 | }
83 |
84 | public bool Resolved
85 | {
86 | get { return type != null; }
87 | }
88 |
89 | public CClass ActualType
90 | {
91 | get { return type; }
92 | private set
93 | {
94 | if (type != value)
95 | {
96 | type = value;
97 | if (owner != null) owner.DoTypeChanged();
98 | }
99 | }
100 | }
101 |
102 | public static implicit operator CClass(CTypeRef tref)
103 | {
104 | return tref.ActualType;
105 | }
106 |
107 | public override bool Equals(object obj)
108 | {
109 | return this == (CTypeRef)obj;
110 | }
111 |
112 | public bool Equals(CTypeRef obj)
113 | {
114 | return this == obj;
115 | }
116 |
117 | public static bool operator ==(CTypeRef l, CTypeRef r)
118 | {
119 | if (!l.Resolved || !r.Resolved)
120 | {
121 | // allow comparisons to Empty
122 | if (l.name == null || r.name == null)
123 | {
124 | if (l.Resolved || r.Resolved)
125 | return false;
126 | return l.name == r.name;
127 | }
128 |
129 | throw new InvalidOperationException("Cannot compare unresolved types");
130 | }
131 | return l.ActualType == r.ActualType;
132 | }
133 |
134 | public static bool operator !=(CTypeRef l, CTypeRef r)
135 | {
136 | return !(l == r);
137 | }
138 |
139 | public override int GetHashCode()
140 | {
141 | if (this.Resolved)
142 | return this.ActualType.GetHashCode();
143 | if (this.name != null)
144 | return this.name.GetHashCode();
145 | return base.GetHashCode();
146 | }
147 | }
148 | }
--------------------------------------------------------------------------------
/AST/CUnaryOperator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public abstract class CUnaryOperator : CExpression, INodeParent
7 | {
8 | private CToken action;
9 | private CExpression rhs;
10 |
11 | public CUnaryOperator(CToken tok, CExpression rhs)
12 | : base(tok)
13 | {
14 | action = tok;
15 | this.rhs = rhs;
16 | rhs.Parent = this;
17 | }
18 |
19 | public CToken Operation
20 | {
21 | get { return action; }
22 | }
23 |
24 | public virtual CExpression Operand
25 | {
26 | get { return rhs; }
27 | }
28 |
29 | void INodeParent.Replace(CNode child, CNode newchild)
30 | {
31 | if (child == rhs)
32 | rhs = (CExpression)newchild;
33 | newchild.Parent = this;
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/AST/CUnionClass.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CUnionType : CClass
7 | {
8 | private List types = new List();
9 | private static int unnamedCount;
10 |
11 | public CUnionType(CToken token, String rawname, String name)
12 | : base(token, "__Unamed_Union" + unnamedCount++)
13 | {
14 | CProgram.Global.AddClass(base.Name, this);
15 | NameToken = CToken.Identifer(token, name, rawname);
16 | CProgram.Global.AddClass(base.Name, this);
17 | }
18 |
19 | public CUnionType(CToken token)
20 | : base(token, "__Unamed_Union" + unnamedCount++)
21 | {
22 | CProgram.Global.AddClass(base.Name, this);
23 | NameToken = CToken.Identifer(token, "", "");
24 | IsObject = false;
25 | }
26 |
27 | [Obsolete("Use Add(CTypeRef tref) instead")]
28 | public virtual void Add(Object type)
29 | {
30 | Add(type, type as string);
31 | }
32 |
33 | [Obsolete("Use Add(CTypeRef tref) instead")]
34 | public virtual void Add(Object type, String rawTypeName)
35 | {
36 | if (type is CTypeRef)
37 | Add((CTypeRef)type);
38 | else if (type is CUnionType)
39 | Add((CUnionType)type);
40 | else if (type is CClass)
41 | Add((CClass)type);
42 | else
43 | Add((string)type, rawTypeName);
44 | }
45 |
46 | [Obsolete("Use Add(CTypeRef tref) instead")]
47 | public virtual void Add(CClass type)
48 | {
49 | Add(new CTypeRef(this, type));
50 | }
51 |
52 | [Obsolete("Use Add(CTypeRef tref) instead")]
53 | public virtual void Add(String type, String rawtype)
54 | {
55 | Add(new CTypeRef(this, CToken.Identifer(null, type, rawtype)));
56 | }
57 |
58 | public virtual void Add(CTypeRef tref)
59 | {
60 | if (tref.Resolved && tref.ActualType is CUnionType)
61 | Add((CUnionType)tref.ActualType);
62 | else
63 | {
64 | string prefix = " Or ";
65 | if (Name == "")
66 | prefix = "";
67 | NameToken =
68 | CToken.Identifer(NameToken, Name + prefix + tref.TypeName.Value,
69 | RawName + prefix + tref.TypeName.RawValue);
70 | types.Add(new CTypeRef(this, tref));
71 | }
72 | }
73 |
74 | public virtual void Add(CUnionType union)
75 | {
76 | foreach (CTypeRef type in union.types)
77 | Add(type);
78 | }
79 |
80 | public override CAttributeList Attributes
81 | {
82 | get
83 | {
84 | CAttributeList cal = new CAttributeList();
85 | cal.Add(base.Attributes);
86 |
87 | if (!types[0].Resolved)
88 | return cal;
89 |
90 | foreach (CAttribute at in types[0].ActualType.Attributes)
91 | {
92 | bool found = true;
93 | IEnumerator it = types.GetEnumerator();
94 | it.MoveNext();
95 | while (found && it.MoveNext())
96 | {
97 | if (!it.Current.Resolved)
98 | found = false;
99 | else if (!it.Current.ActualType.Attributes.contains(at.Name))
100 | found = false;
101 | }
102 |
103 | if (found)
104 | cal.Add(at.NameToken, at.Parameters, new CTypeRef(at, at.Type));
105 | }
106 |
107 | return cal;
108 | }
109 | }
110 |
111 | public virtual String UpdateMembers(IVisitor checker)
112 | {
113 | if (types.Count == 0)
114 | return "Empty enum type used";
115 |
116 | bool isObject = true;
117 | for (int i = 0; i < types.Count; i++)
118 | {
119 | CTypeRef otype = types[i];
120 | if (!otype.Resolved)
121 | {
122 | CClass ntype = CProgram.Global.FindClass(otype.TypeName);
123 | if (ntype == null)
124 | return "Cannot find type " + otype.TypeName.RawValue;
125 | otype.InternalLoad(ntype);
126 | }
127 | types[i] = otype;
128 | types[i].ActualType.Accept(checker);
129 | isObject = isObject && otype.ActualType.IsObject;
130 | }
131 | IsObject = isObject;
132 |
133 | base.ClearMembers();
134 | Scope.Clear();
135 |
136 | foreach (CMember member in types[0].ActualType.InheritedMemberIterator)
137 | {
138 | bool found;
139 | if (member is CMemberOverload)
140 | found = false;
141 | else// Unions can only access public members
142 | found = member.Visibility == TokenTypes.visPublic;
143 |
144 |
145 | IEnumerator it = types.GetEnumerator();
146 | it.MoveNext();
147 | while (found && it.MoveNext())
148 | {
149 | CClass type = it.Current.ActualType;
150 | CMember luMember = type.LookupMember(member.Name);
151 | if (luMember == null)
152 | found = false;
153 | else if (luMember.MemberType != member.MemberType)
154 | // one's a method, the other's a field, or etc...
155 | found = false;
156 | else if (luMember.Visibility != TokenTypes.visPublic)
157 | found = false;
158 | else
159 | {
160 | switch (luMember.MemberType)
161 | {
162 | case "method":
163 | CMethod metho = (CMethod)member;
164 | CMethod luMetho = (CMethod)luMember;
165 | // already checked return type, let's try the parameters
166 | if (metho.Function.Arguments.Count != luMetho.Function.Arguments.Count)
167 | found = false;
168 | break;
169 | case "property":
170 | found = UnionProperty((CProperty)member, (CProperty)luMember);
171 | // dur
172 | break;
173 | case "field":
174 | // already checked return type, nothing left to check
175 | break;
176 | case "override":
177 | found = false;// dur
178 | break;
179 | }
180 | }
181 | }
182 | if (found)
183 | {
184 | CMember fmember;
185 | switch (member.MemberType)
186 | {
187 | case "method":
188 | fmember = new CMethod((CMethod)member, true);
189 | break;
190 | case "property":
191 | fmember = new CProperty((CProperty)member, true);
192 | break;
193 | case "field":
194 | fmember = new CField((CField)member, true);
195 | break;
196 | case "override":
197 | fmember = new CMemberOverload((CMemberOverload)member, true);
198 | break;
199 | default:
200 | throw new InvalidOperationException();
201 | }
202 | SetMember(member.Name, fmember);
203 | Scope.add(fmember);
204 | }
205 | }
206 |
207 | bool hasDefault = true;
208 | DefaultMember = null;
209 | foreach (CTypeRef _class in types)
210 | {
211 | var memberBase = ((CClass)types[0]).DefaultMember;
212 | var member = _class.ActualType.DefaultMember;
213 | if ( memberBase == null ||
214 | member == null ||
215 | !UnionProperty((CProperty)memberBase, (CProperty) member))
216 | {
217 | hasDefault = false;
218 | break;
219 | }
220 | }
221 | if (hasDefault)
222 | DefaultMember = ((CClass)types[0]).DefaultMember;
223 |
224 | return null;
225 | }
226 |
227 | private static bool UnionProperty(CProperty propo, CProperty luPropo)
228 | {
229 | for (int i = 0; i < 3; i++)
230 | {
231 | if ((propo.Declared[i] == null) != (luPropo.Declared[i] == null))
232 | return false;
233 | else if (propo.Declared[i] != null &&
234 | ((CFunction)propo.Declared[i]).Arguments.Count != ((CFunction)luPropo.Declared[i]).Arguments.Count)
235 | return false;
236 | }
237 | return true;
238 | }
239 |
240 | public List Types
241 | {
242 | get { return types; }
243 | set { types = value; }
244 | }
245 |
246 | protected override bool canUnionConvert(CClass klass)
247 | {
248 | foreach (CTypeRef tref in types)
249 | {
250 | if (tref.ActualType == null || !tref.ActualType.canConvertTo(klass))
251 | return false;
252 | }
253 | return true;
254 | }
255 |
256 | public override bool IsEnum
257 | {
258 | get
259 | {
260 | foreach (CTypeRef tref in types)
261 | {
262 | if (!tref.Resolved || !tref.ActualType.IsEnum)
263 | return false;
264 | }
265 | return true;
266 | }
267 | }
268 |
269 | public override bool IsInterface
270 | {
271 | get
272 | {
273 | foreach (CTypeRef tref in types)
274 | {
275 | if (!tref.Resolved || !tref.ActualType.IsInterface)
276 | return false;
277 | }
278 | return true;
279 | }
280 | }
281 | }
282 | }
--------------------------------------------------------------------------------
/AST/CVariable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CVariable : CVariableBase, INodeParent
7 | {
8 | private CParameters arrayDimsinit;
9 | private CExpression init;
10 | private bool member;
11 | private CNode rootForRedim;
12 | private CField field;
13 | private CDim dim;
14 | private Mono.Cecil.FieldDefinition cecilField;
15 | private bool firstAccessIsRedimPreserve = false;
16 |
17 | public CVariable(CToken name, bool shared, CTypeRef tref, CParameters arrayDimsinit, CExpression init, CDim parent)
18 | : base(name, shared)
19 | {
20 | this.dim = parent;
21 | this.name = name;
22 | base.LoadType(tref);
23 | this.init = init;
24 | if (init != null)
25 | init.Parent = this;
26 | member = false;
27 | this.arrayDimsinit = arrayDimsinit;
28 | }
29 |
30 | public override void LoadType(CClass type)
31 | {
32 | base.LoadType(type);
33 |
34 | EnsureDiminsionInitializerIsValid();
35 | }
36 |
37 | public override void LoadType(CTypeRef tref)
38 | {
39 | base.LoadType(tref);
40 |
41 | EnsureDiminsionInitializerIsValid();
42 | }
43 |
44 | public bool FirstAccessIsRedimPreserve
45 | {
46 | get { return firstAccessIsRedimPreserve; }
47 | set { firstAccessIsRedimPreserve = value; }
48 | }
49 |
50 | public override bool IsField
51 | {
52 | get { return member; }
53 | set { member = value; }
54 | }
55 |
56 |
57 | public CDim Dim
58 | {
59 | get { return this.dim; }
60 | }
61 |
62 | public CNode RootForRedim
63 | {
64 | get { return rootForRedim; }
65 | set { rootForRedim = value; }
66 | }
67 |
68 | public CExpression Initializer
69 | {
70 | get { return init; }
71 | protected set
72 | {
73 | init = value;
74 | if (init != null)
75 | init.Parent = this;
76 | }
77 | }
78 |
79 | public CParameters DimensionInitializer
80 | {
81 | get { return arrayDimsinit; }
82 | }
83 |
84 | public override void Accept(IVisitor visitor)
85 | {
86 | visitor.VisitVariable(this);
87 | }
88 |
89 | public override void ConvertToArray(CClass type, int count)
90 | {
91 | base.ConvertToArray(type, count);
92 |
93 | EnsureDiminsionInitializerIsValid();
94 | }
95 |
96 | private void EnsureDiminsionInitializerIsValid()
97 | {
98 | CDictionaryType dict = Type.ActualType as CDictionaryType;
99 | if (dict != null)
100 | return;
101 |
102 | CArrayType array = Type.ActualType as CArrayType;
103 | if (array == null || arrayDimsinit != null)
104 | return;
105 |
106 | int count = array.Dimensions;
107 | CParameters @params = new CParameters();
108 | for (int i = 0; i < count; i++)
109 | @params.Unnamed.Add(null);
110 |
111 | arrayDimsinit = @params;
112 | }
113 |
114 | public Mono.Cecil.FieldDefinition CecilField
115 | {
116 | get { return cecilField; }
117 | set { cecilField = value; }
118 | }
119 |
120 | public CField Field
121 | {
122 | get { return field; }
123 | set { field = value; }
124 | }
125 |
126 | #region INodeParent Members
127 |
128 | void INodeParent.Replace(CNode child, CNode newchild)
129 | {
130 | if (child == Initializer)
131 | Initializer = (CExpression)newchild;
132 | }
133 |
134 | #endregion
135 | }
136 | }
--------------------------------------------------------------------------------
/AST/CVariableBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public abstract class CVariableBase : CNode, IVariable, IAttributed
7 | {
8 | protected CVariableBase(CToken token, bool shared)
9 | : base(token)
10 | {
11 | this.shared = shared;
12 | }
13 |
14 | protected CVariableBase(CToken token)
15 | : this(token, false)
16 | {
17 | }
18 |
19 | protected CToken name;
20 | private CAttributeList attribs = new CAttributeList();
21 | protected bool accessedBeforeUsed = false;
22 | protected int assignCount = 0;
23 | protected int accessCount = 0;
24 | private CClass containingClass;
25 | private CFunction containingFunction;
26 | private bool shared = false;
27 | private bool external = false;
28 |
29 | public virtual CToken Name
30 | {
31 | get { return name; }
32 | }
33 |
34 | String IVariable.Name
35 | {
36 | get { return name.Value; }
37 | }
38 |
39 | public CClass ContainingClass
40 | {
41 | get { return containingClass; }
42 | set { containingClass = value; }
43 | }
44 |
45 | public CFunction ContainingFunction
46 | {
47 | get { return containingFunction; }
48 | set { containingFunction = value; }
49 | }
50 |
51 | public virtual bool AccessedBeforeUsed
52 | {
53 | get { return accessedBeforeUsed; }
54 | }
55 |
56 | public virtual int AssignmentCount
57 | {
58 | get { return assignCount; }
59 | }
60 |
61 | public virtual int AccessCount
62 | {
63 | get { return accessCount; }
64 | }
65 |
66 | string IVariable.RawName
67 | {
68 | get { return name.RawValue; }
69 | }
70 |
71 | public bool IsArray
72 | {
73 | get { return Type.ActualType is CArrayType && !(Type.ActualType is CDictionaryType); }
74 | }
75 |
76 | public string TypeName
77 | {
78 | get
79 | {
80 | if (Type.TypeName != null)
81 | return Type.TypeName.Value;
82 | return null;
83 | }
84 | }
85 |
86 | public CAttributeList Attributes
87 | {
88 | get { return attribs; }
89 | }
90 |
91 | public abstract bool IsField { get; set; }
92 |
93 | public bool IsShared
94 | {
95 | get { return shared; }
96 | }
97 |
98 | public virtual void incAssignmentCount(CClass currentclass, CFunction currentfunction)
99 | {
100 | assignCount++;
101 | }
102 |
103 | public virtual void incAccessCount(CClass currentclass, CFunction currentfunction)
104 | {
105 | if (assignCount == 0)
106 | accessedBeforeUsed = true;
107 | accessCount++;
108 | }
109 |
110 | public virtual bool canAssign(CClass currentclass, CFunction currentfunction)
111 | {
112 | return true;
113 | }
114 |
115 | public virtual void ConvertToArray(CClass type, int count)
116 | {
117 | base.LoadType(type);
118 | }
119 |
120 | public bool IsExternallyReferenced
121 | {
122 | get { return external; }
123 | }
124 |
125 | public void SetExternallyReferenced()
126 | {
127 | external = true;
128 | }
129 | }
130 | }
--------------------------------------------------------------------------------
/AST/CWhile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CWhile : CStatement, INodeParent
7 | {
8 | private CExpression condition;
9 | private CStatementBlock statements = new CStatementBlock();
10 |
11 | public CWhile(CToken token, CExpression condition)
12 | : base(token)
13 | {
14 | this.condition = condition;
15 | this.condition.Parent = this;
16 | }
17 |
18 | public CExpression Condition
19 | {
20 | get { return condition; }
21 | }
22 |
23 | public CStatementBlock Statements
24 | {
25 | get { return statements; }
26 | }
27 |
28 | public override void Accept(IVisitor visitor)
29 | {
30 | visitor.VisitWhile(this);
31 | }
32 |
33 | void INodeParent.Replace(CNode child, CNode newchild)
34 | {
35 | if (child == condition)
36 | condition = (CExpression)newchild;
37 | newchild.Parent = this;
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/AST/CWith.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CWith : CStatement, INodeParent
7 | {
8 | private CExpression withObj;
9 | private CStatementBlock statements = new CStatementBlock();
10 |
11 | public CWith(CToken token, CExpression value)
12 | : base(token)
13 | {
14 | withObj = value;
15 | value.Parent = this;
16 | }
17 |
18 | public CStatementBlock Statements
19 | {
20 | get { return statements; }
21 | }
22 |
23 | public CExpression Value
24 | {
25 | get { return withObj; }
26 | }
27 |
28 | public override void Accept(IVisitor visitor)
29 | {
30 | visitor.VisitWith(this);
31 | }
32 |
33 | #region INodeParent Members
34 |
35 | void INodeParent.Replace(CNode child, CNode newchild)
36 | {
37 | if (withObj == child)
38 | {
39 | withObj = (CExpression)newchild;
40 | newchild.Parent = this;
41 | }
42 | }
43 |
44 | #endregion
45 | }
46 | }
--------------------------------------------------------------------------------
/AST/CWithAccess.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public class CWithAccess : CAccess
7 | {
8 | public CWithAccess(CToken tok)
9 | : base(tok, tok)
10 | {
11 | }
12 |
13 | public override void Accept(IVisitor visit)
14 | {
15 | visit.VisitWithAccess(this);
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/AST/IAttributed.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | internal interface IAttributed
7 | {
8 | CAttributeList Attributes { get; }
9 | }
10 | }
--------------------------------------------------------------------------------
/AST/IHasVisibility.cs:
--------------------------------------------------------------------------------
1 | namespace FogCreek.Wasabi.AST
2 | {
3 | public interface IHasVisibility
4 | {
5 | CClass DeclaringClass { get; }
6 | TokenTypes Visibility { get; }
7 | bool IsStatic { get; }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/AST/IVariable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | public interface IVariable
7 | {
8 | CToken Token { get; }
9 | String Name { get; }
10 | CTypeRef Type { get; }
11 | bool IsArray { get; }
12 | bool AccessedBeforeUsed { get; }
13 | int AssignmentCount { get; }
14 | int AccessCount { get; }
15 |
16 | string RawName { get; }
17 |
18 | void incAssignmentCount(CClass currentclass, CFunction currentfunction);
19 | void incAccessCount(CClass currentclass, CFunction currentfunction);
20 | bool canAssign(CClass currentclass, CFunction currentfunction);
21 |
22 | void SetExternallyReferenced();
23 | }
24 | }
--------------------------------------------------------------------------------
/AST/IVisitor.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace FogCreek.Wasabi.AST
3 | {
4 | public interface IVisitor
5 | {
6 | void VisitBlock(CStatementBlock statements);
7 | void VisitAssignment(CAssignment assign);
8 | void VisitCase(CCase ccase);
9 | void VisitClass(CClass cclas);
10 | void VisitComment(CComment comment);
11 | void VisitConcat(CConcat concat);
12 | void VisitConst(CConst cconst);
13 | void VisitDim(CDim dim);
14 | void VisitDo(CDo cdo);
15 | void VisitExit(CExit exit);
16 | void VisitReturn(CReturn _return);
17 | void VisitParenExpression(CParenExpression exp);
18 | void VisitFor(CFor cfor);
19 | void VisitForEach(CForEach _foreach);
20 | void VisitFunction(CFunction function);
21 | void VisitHtml(CHtml html);
22 | void VisitIf(CIf cif);
23 | void VisitMemberVariable(CMemberVariable membervariable);
24 | void VisitReDim(CReDim redim);
25 | void VisitSelect(CSelect select);
26 | void VisitSpecialEqual(CSpecialEqual specialequal);
27 | void VisitStatement(CStatement statement);
28 | void VisitToken(CToken token);
29 | void VisitWhile(CWhile cwhile);
30 | void VisitWith(CWith with);
31 |
32 | void VisitAccess(CAccess access);
33 | void VisitComparison(CComparison compare);
34 | void VisitConstantExpression(CConstantExpression constant);
35 | void VisitDefaultAccess(CDefaultAccess access);
36 | void VisitLogic(CLogic logic);
37 | void VisitMath(CMath math);
38 | void VisitMathUnary(CMathUnary math);
39 | void VisitMemberAccess(CMemberAccess access);
40 | void VisitNew(CNew _new);
41 | void VisitNot(CNot not);
42 | void VisitOnError(COnError onerror);
43 | void VisitParameters(CParameters parameters);
44 | void VisitThisAccess(CThisAccess access);
45 | void VisitWithAccess(CWithAccess access);
46 | void VisitTernary(CTernary ternary);
47 |
48 | void VisitVariable(CVariable var);
49 | void VisitPictureOf(CPictureOfExpression pic);
50 | void VisitOption(COption option);
51 |
52 | void VisitLambdaExpression(CLambdaExpression lambda);
53 |
54 | void VisitProgram(CProgram program);
55 | void VisitFile(CFile file);
56 | void VisitDirective(CDirective directive);
57 |
58 | void VisitInterface(CInterface iface);
59 | void VisitEnum(CEnum eration);
60 |
61 | void VisitTry(CTry _try);
62 | void VisitCatch(CCatch _catch);
63 | void VisitFinally(CFinally _finally);
64 | void VisitThrow(CThrow _throw);
65 |
66 | void VisitLock(CLock @lock);
67 | void VisitOnExit(COnExit onexit);
68 | void VisitBaseAccess(CBaseAccess _base);
69 | void VisitGlobalAccess(CGlobalAccess cGlobalAccess);
70 | void VisitOptionalByRef(COptionalByRef cOptionalByRef);
71 | void VisitAttribute(CAttribute cAttribute);
72 | }
73 | }
--------------------------------------------------------------------------------
/AST/TokenTypes.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace FogCreek.Wasabi.AST
5 | {
6 | // this defines all the constants we use throughout thistle- not just token types
7 | public enum TokenTypes
8 | {
9 | maskPreserveCase = 0x10000000,
10 | maskTokenNumber = 0x000000FF,
11 | maskEscaped = 0x20000000,
12 | maskExpConnector = 0x40000000,
13 | maskPreprocDir = unchecked((int)0x80000000),
14 | maskVisibility = 0x01000000,
15 |
16 | // token types
17 | compareOp = 0x50000001, // <, <=, >, >=, <>
18 | str = 0x10000002, // "blah", strings
19 | character = 0x1000002b, // "c"c characters
20 | number = 0x00000003, // for now any int or double . . .
21 | comment = 0x10000004, // 'blah
22 | oParen = 0x50000005, // (
23 | cParen = 0x50000006, // )
24 | oCurly = 0x50000024, // {
25 | cCurly = 0x50000025, // }
26 | html = 0x10000007, // some html blocks
27 | arithOp = 0x50000008, // +,-,*,/
28 | strConcat = 0x50000009, // the &
29 | dot = 0x5000000A, // .
30 | colon = 0x1000000B, // :
31 | newline = 0x1000000C, // the newline char (need to make : into newline)
32 | space = 0x1000000D, // this is for whitespace
33 | equal = 0x5000000E, // =
34 | comma = 0x5000000F, // commas seperate parameters etc
35 | underscore = 0x10000010, // imp for rolling over lines
36 | pound = 0x00000011, // # sign. used for dates
37 | aspDirective = 0x00000023, // ASP directive @
38 | questionMark = 0x5000002b, // ternary conditional operator
39 |
40 | // identifier like tokens
41 | keyword = 0x00000014, // empty, false, nothing, dbnull, true
42 | vbFunc = 0x00000015, // some vb function like Cstr
43 | declaration = 0x00000016, // Class, Const, Dim, ReDim, Function, Sub . . .
44 | assignment = 0x00000017, // set
45 | controlFlow = 0x00000018, // if, then, else . . .
46 | conjunction = 0x4000001A, // and, or, not
47 | call = 0x0000001B, // Call
48 | me = 0x0000001C, // this, me
49 | identifier = 0x0000001D, // any word thats not a keyword (like a var or func)
50 | visPublic = 0x0100001E,
51 | visPrivate = 0x0100001F,
52 | visProtected = 0x01000029,
53 | visInternal = 0x0100002a,
54 |
55 | AspStart = unchecked((int)0x80000020),
56 | XxxEnd = unchecked((int)0x80000022),
57 | PreprocessorIf = unchecked((int)0x80000026),
58 | PreprocessorEndIf = unchecked((int)0x80000027),
59 | PreprocessorElse = unchecked((int)0x80000028),
60 |
61 | EOF = 0x000FFFF, // the end of a file
62 | EMPTY = 0, // used to for an invalid value;
63 | LastToken = 0x0000002c,
64 | }
65 |
66 | public static class TokenStrings
67 | {
68 | // specific words to look for that have special meaning.
69 | // within the list of the 'vbfuncs' are also functions that we have
70 | public static readonly String keywords =
71 | "false|nothing|dbnull|true|byref|byval|erase|preserve|on|pictureof|optional|shared|paramarray";
72 |
73 | public static readonly String declarations =
74 | "abstract|class|const|dim|redim|function|sub|lambda|option|property|default|union|inherits|implements|overridable|override|interface|sealed|enum|static";
75 |
76 | public static readonly String assignments = "set";
77 | public static readonly String callStatement = "call";
78 | public static readonly String meObject = "me|this|base|global";
79 |
80 | public static readonly String controlFlows =
81 | "do|until|in|select|case|while|loop|for|to|else|next|exit|each|wend|if|then|with|elseif|end|resume|goto|step|try|catch|finally|throw|return";
82 |
83 | public static readonly String vbFuncs =
84 | "getarray|setarray|getfieldsize|setlocale|isempty|getlocale|rnd|sizeofmatches|getmatchat|getsubmatchat|getappvar|setappvar|formatnumber|dateserial|dateadd|datediff|cdate|isdate|formatdatetime|date|hour|minute|second|now|year|month|day|weekday|getAppVar|setAppVar|cbyte|instrrev|instr|string|now|replace|array|lbound|ubound|right|split|trim|ltrim|rtrim|clng|cint|cstr|isnumeric|strcomp|len|lenb|left|isdbnull|mid|cdbl|lcase|typename|round|asc|ascw|chr|chrw|int|cbool|hex|ucase|sqr|isarray|isobject|abs|log|exp|space|join|strreverse|getref|timevalue|randomize|timer";
85 |
86 | public static readonly String conjunctions = "and|or|not|imp|xor|eqv";
87 | public static readonly String arithOpWords = "mod";
88 |
89 | public static string ToString(TokenTypes type)
90 | {
91 | switch (type)
92 | {
93 | case TokenTypes.oParen: return "'('";
94 | case TokenTypes.cParen: return "')'";
95 | case TokenTypes.oCurly: return "'{'";
96 | case TokenTypes.cCurly: return "'}'";
97 | }
98 | return type.ToString();
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/BuiltIns.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using FogCreek.Wasabi.AST;
5 |
6 | namespace FogCreek.Wasabi
7 | {
8 | public static class BuiltIns
9 | {
10 | public static readonly CClass Byte;
11 | public static readonly CClass Int32;
12 | public static readonly CClass Int64;
13 | public static readonly CClass Character;
14 | public static readonly CClass String;
15 | public static readonly CClass Boolean;
16 | public static readonly CClass Date;
17 | public static readonly CClass Double;
18 | public static readonly CClass Object;
19 | public static readonly CClass Variant;
20 | public static readonly CClass DbNull;
21 | public static readonly CClass Nothing;
22 | public static readonly CClass Void;
23 | public static readonly CClass FunctionPlaceHolder;
24 | public static readonly CClass SubPlaceHolder;
25 |
26 | public static readonly CFunction Array;
27 | public static readonly CFunction Dictionary;
28 | public static readonly CFunction GetRef;
29 |
30 | public static readonly CClass SystemArray;
31 |
32 | static BuiltIns()
33 | {
34 | /* These aren't fully resolved; we need to use Cecil to load the appropriate .NET type defitinions in.
35 | See ClrImporter.LoadBuiltins. */
36 | Variant = new CClass("__Variant", null);
37 | Byte = new CClass("Byte", false);
38 | String = new CClass("String", true);
39 | Int32 = new CClass("Int32", true);
40 | Int64 = new CClass("Int64", true);
41 | Character = new CClass("Character", false);
42 | Boolean = new CClass("Boolean", true);
43 | Date = new CClass("Date", true);
44 | Double = new CClass("Double", true);
45 | Object = Variant;
46 | DbNull = new CClass("DbNull", false);
47 | Nothing = new CClass("Nothing", false);
48 | Nothing.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(null, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
49 | Void = new CClass("__Void", false);
50 | FunctionPlaceHolder = new CClass("__FunctionPlaceHolder", false);
51 | FunctionPlaceHolder.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(null, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
52 | SubPlaceHolder = new CClass("__SubPlaceHolder", false);
53 | SubPlaceHolder.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(null, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
54 |
55 | SetupGlobalTypes();
56 |
57 | CArgumentList arrArgs = new CArgumentList();
58 | arrArgs.Add(new CArgument(CToken.Keyword(null, "byval"),
59 | CToken.Identifer(null, "arglist"),
60 | new CTypeRef(null, Variant)));
61 | Array = new CFunction(CToken.Identifer(null, "Array"), "Array", "array", TokenTypes.visPublic, FunctionType.Function,
62 | arrArgs, new CTypeRef(null, new CArrayType(new CTypeRef(null, Variant), 1)));
63 | Array.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(null, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
64 |
65 | CArgumentList dicArgs = new CArgumentList();
66 | dicArgs.Add(new CArgument(CToken.Keyword(null, "byval"),
67 | CToken.Identifer(null, "arglist"),
68 | new CTypeRef(null, Variant)));
69 | Dictionary = new CFunction(CToken.Identifer(null, "Dictionary"), "Dictionary", "dictionary", TokenTypes.visPublic, FunctionType.Function,
70 | dicArgs, new CTypeRef(null, new CDictionaryType(new CTypeRef(null, Variant))));
71 | Dictionary.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(null, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
72 |
73 | CArgumentList refArgs = new CArgumentList();
74 | refArgs.Add(new CArgument(CToken.Keyword(null, "byval"),
75 | CToken.Identifer(null, "func"),
76 | new CTypeRef(null, BuiltIns.String)));
77 | GetRef = new CFunction(CToken.Identifer(null, "GetRef"), "GetRef", "getref", TokenTypes.visPublic, FunctionType.Function, refArgs,
78 | new CTypeRef(null, BuiltIns.FunctionPlaceHolder));
79 | GetRef.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(null, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
80 |
81 | // add string ienumerator interface
82 | CToken ifaceName = CToken.Identifer(null, "System.Collections.Generic.IEnumerable`1");
83 | CInterface iface = new CInterface(ifaceName, ifaceName);
84 | iface.GenericParameters.Add(Character);
85 | String.AddInterface(new CTypeRef(null, iface));
86 | }
87 |
88 | private static void SetupGlobalTypes()
89 | {
90 | Byte.IsNumeric = Int32.IsNumeric = Double.IsNumeric = Date.IsNumeric = Int64.IsNumeric = true;
91 | Character.IsObject = Byte.IsObject = String.IsObject = Int32.IsObject = Boolean.IsObject = Date.IsObject = Double.IsObject = false;
92 |
93 | Object.IsObject = true;
94 |
95 | // Conversion matrix
96 | //
97 | // SIDBFL
98 | // S100000
99 | // I110011
100 | // D101000
101 | // B100100
102 | // F100010
103 | // L100001
104 | //
105 |
106 | Int32.EnableConversionTo(Double);
107 | Int32.EnableConversionTo(Int64);
108 |
109 | DbNull.IsObject = false;
110 |
111 | Variant.IsInferable = DbNull.IsInferable = Nothing.IsInferable = false;
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/ClrImporter.cs:
--------------------------------------------------------------------------------
1 | using FogCreek.Wasabi.AST;
2 | using Mono.Cecil;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | using CustomAttributeCollection = Mono.Collections.Generic.Collection;
10 |
11 | namespace FogCreek.Wasabi
12 | {
13 | ///
14 | /// Just enough to be able to declare return types! Very incomplete!
15 | ///
16 | public class ClrImporter
17 | {
18 | public static void LoadBuiltins(CProgram program)
19 | {
20 | ImportType(program, SearchAssembliesForType(program, "System.Object"), BuiltIns.Variant);
21 | ImportType(program, SearchAssembliesForType(program, "System.String"), BuiltIns.String);
22 |
23 | CClass vtype = program.FindClass("System.ValueType");
24 |
25 | ImportType(program, SearchAssembliesForType(program, "System.Byte"), BuiltIns.Byte);
26 | BuiltIns.Byte.ForceSetBaseClass(vtype);
27 | ImportType(program, SearchAssembliesForType(program, "System.Int32"), BuiltIns.Int32);
28 | BuiltIns.Int32.ForceSetBaseClass(vtype);
29 | ImportType(program, SearchAssembliesForType(program, "System.Int64"), BuiltIns.Int64);
30 | BuiltIns.Int64.ForceSetBaseClass(vtype);
31 | ImportType(program, SearchAssembliesForType(program, "System.Char"), BuiltIns.Character);
32 | BuiltIns.Character.ForceSetBaseClass(vtype);
33 | ImportType(program, SearchAssembliesForType(program, "System.Boolean"), BuiltIns.Boolean);
34 | BuiltIns.Boolean.ForceSetBaseClass(vtype);
35 | ImportType(program, SearchAssembliesForType(program, "System.DateTime"), BuiltIns.Date);
36 | BuiltIns.Date.ForceSetBaseClass(vtype);
37 | ImportType(program, SearchAssembliesForType(program, "System.Double"), BuiltIns.Double);
38 | BuiltIns.Double.ForceSetBaseClass(vtype);
39 |
40 | BuiltIns.Variant.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Variant, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
41 | BuiltIns.Object.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Object, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
42 | BuiltIns.String.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.String, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
43 | BuiltIns.Byte.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Byte, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
44 | BuiltIns.Int32.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Int32, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
45 | BuiltIns.Int64.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Int64, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
46 | BuiltIns.Character.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Character, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
47 | BuiltIns.Boolean.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Boolean, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
48 | BuiltIns.Date.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Date, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
49 | BuiltIns.Double.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Double, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
50 | }
51 |
52 | private static TypeDefinition SearchAssembliesForType(CProgram program, string name)
53 | {
54 | foreach (var asm in program.Assemblies)
55 | {
56 | var typed = asm.MainModule.Types.FirstOrDefault(td => td.FullName == name);
57 | if (typed != null)
58 | return typed;
59 | }
60 |
61 | return null;
62 | }
63 |
64 | private static bool IsClsCompliant(CustomAttributeCollection customAttributeCollection)
65 | {
66 | foreach (CustomAttribute attr in FindAttributes(customAttributeCollection, "System.CLSCompliantAttribute"))
67 | {
68 | if (attr.ConstructorArguments.Count > 0)
69 | return (bool)attr.ConstructorArguments[0].Value;
70 | }
71 | return true;
72 | }
73 |
74 | private static IEnumerable FindAttributes(CustomAttributeCollection attrs, string name)
75 | {
76 | if (attrs != null)
77 | foreach (CustomAttribute attr in attrs)
78 | {
79 | if (attr.Constructor.DeclaringType.FullName == name)
80 | yield return attr;
81 | }
82 | }
83 |
84 | private static void ImportType(CProgram program, TypeDefinition typed, CClass type)
85 | {
86 | if (type.CecilType != null)
87 | return;
88 | type.CecilType = typed;
89 |
90 | if (typed.GenericParameters.Count > 0 || !IsClsCompliant(typed.CustomAttributes))
91 | return;
92 |
93 |
94 | if (typed.IsEnum)
95 | {
96 | type.IsObject = false;
97 | type.IsNumeric = true;
98 | }
99 |
100 | type.IsObject = !typed.IsValueType;
101 |
102 | type.SetSemanticallyComplete();
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/CompileException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace FogCreek.Wasabi
4 | {
5 | [Serializable]
6 | public class CompileException : ApplicationException
7 | {
8 | internal readonly string filename;
9 | internal readonly string type;
10 | internal readonly int errno;
11 | internal readonly int line;
12 | internal readonly string source;
13 |
14 | private CompileException(string filename, string type, int errno, string message, int line, string source)
15 | : base(escape(message))
16 | {
17 | this.filename = filename;
18 | this.type = type;
19 | this.errno = errno;
20 | this.line = line;
21 | this.source = escape(source);
22 | }
23 |
24 | internal static string escape(string str)
25 | {
26 | str = str.Replace("\n", @"\n");
27 | str = str.Replace("\r", @"\r");
28 | str = str.Replace("\t", @"\t");
29 | return str;
30 | }
31 |
32 | internal static CompileException codegenFailed(string p)
33 | {
34 | return new CompileException("", "C", 1, p, 0, "");
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/Compiler.cs:
--------------------------------------------------------------------------------
1 | using FogCreek.Wasabi.AST;
2 |
3 | namespace FogCreek.Wasabi
4 | {
5 | public enum CompilerPhase
6 | {
7 | Parsing,
8 | TypeChecking,
9 | XmlGenerating,
10 | CodeGenerating,
11 | }
12 |
13 | public class Compiler
14 | {
15 | public static Compiler Current { get; set; }
16 |
17 | public bool DefaultNamespaceSet { get; set; }
18 | public CToken DefaultNamespace { get; set; }
19 |
20 |
21 | public AST.NodeStateMode CurrentMode { get; set; }
22 |
23 | public CompilerPhase CurrentPhase { get; set; }
24 |
25 | public string OutputPath { get; set; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Example/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Example/Example.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {C16DB98C-655F-493E-8751-9AC8A3ACC6F2}
8 | Exe
9 | Properties
10 | Example
11 | Example
12 | v4.5.1
13 | 512
14 |
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 | False
38 | ..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.dll
39 |
40 |
41 | ..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Mdb.dll
42 |
43 |
44 | ..\packages\Mono.Cecil.0.9.6.1\lib\net45\Mono.Cecil.Pdb.dll
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | {19dfae1f-fb84-4771-b6d7-f4526875a6e1}
64 | WasabiRoslynGenerator
65 | True
66 |
67 |
68 |
69 |
76 |
--------------------------------------------------------------------------------
/Example/Program.cs:
--------------------------------------------------------------------------------
1 | using FogCreek.Wasabi;
2 | using FogCreek.Wasabi.AST;
3 | using FogCreek.Wasabi.CodeGenerators;
4 | using System;
5 | using System.IO;
6 | using System.Linq;
7 |
8 | namespace Example
9 | {
10 | class Program
11 | {
12 | /// A single optional arg tells the program where to cram its output
13 | static int Main()
14 | {
15 | CProgram.Global.Assemblies.Add(new Mono.Cecil.DefaultAssemblyResolver().Resolve(typeof(object).Assembly.FullName));
16 |
17 | ClrImporter.LoadBuiltins(CProgram.Global);
18 |
19 | var compiler = Compiler.Current = new Compiler
20 | {
21 | DefaultNamespaceSet = true,
22 | DefaultNamespace = new CToken(null, TokenTypes.identifier, "Output"),
23 | OutputPath = "was_out"
24 | };
25 |
26 | var rg = new RoslynGenerator();
27 | IVisitor irg = rg;
28 |
29 | irg.VisitProgram(CProgram.Global);
30 | irg.VisitFile(FakeFile);
31 |
32 | rg.RootFile("root.cs");
33 | return 0;
34 | }
35 |
36 | private const string FILE = "example.was";
37 |
38 | public static CFile FakeFile
39 | {
40 | get
41 | {
42 | var file = new CFile(FILE, Path.Combine(Directory.GetCurrentDirectory(), FILE));
43 | file.Statements.Add(MainClass);
44 |
45 | return file;
46 | }
47 | }
48 |
49 | public static CClass MainClass
50 | {
51 | get
52 | {
53 | var @class = new CClass(new CToken(FILE, TokenTypes.identifier, "Example"), "Example");
54 |
55 | @class.SetClassMember("Main", new CMethod(MainFunc));
56 |
57 | @class.SetSemanticallyComplete();
58 |
59 | return @class;
60 | }
61 | }
62 |
63 | public static CFunction MainFunc
64 | {
65 | get
66 | {
67 | var func = new CFunction(new CToken(FILE, TokenTypes.identifier, "Main"),
68 | "Main", "Main",
69 | TokenTypes.visPrivate,
70 | CFunction.vbFunction,
71 | new CArgumentList(),
72 | BuiltIns.Int32.Type);
73 | func.IsStatic = true;
74 |
75 | AddBody(func.Statements);
76 |
77 | return func;
78 | }
79 | }
80 |
81 | public static void AddBody(CStatementBlock block)
82 | {
83 | block.Add(new CComment(new CToken(FILE, TokenTypes.comment, "' This is an example"), " This is an example"));
84 |
85 | block.Add(new CReturn(new CToken(FILE, TokenTypes.keyword, "Return"))
86 | {
87 | Expression = new CConstantExpression(new CToken(FILE, TokenTypes.number, "5"))
88 | });
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/Example/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Example")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Example")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("3195facb-bdab-410b-9889-4415439d627b")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/ICodeGenVisitor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using FogCreek.Wasabi.AST;
4 |
5 | namespace FogCreek.Wasabi
6 | {
7 | internal interface IInterceptor
8 | {
9 | void Option(COption option, CodeGenVisitor generator);
10 | void EnterFunction(CFunction function, CodeGenVisitor generator);
11 | void ExitFunction(CFunction function, CodeGenVisitor generator);
12 | }
13 |
14 | internal interface ICodeGenAcceptor : IVisitor
15 | {
16 | Object PreAcceptThen(CIf cif, Object state);
17 | void PreAcceptElse(CIf cif, Object state);
18 | void PreAcceptEndIf(CIf cif, Object state);
19 | void EnterFunction(CFunction function);
20 | void ExitFunction(CFunction function);
21 | }
22 |
23 | public interface ICodeGenVisitor : IVisitor
24 | {
25 | void InstrumentNode(CNode node, int num);
26 | void PreVisitFile(CFile file);
27 |
28 | IVisitor Acceptor { get; set; }
29 |
30 | void print(string s);
31 | void println(string s);
32 | void println();
33 | }
34 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Fog Creek Software, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace FogCreek.Wasabi
4 | {
5 | static class Program
6 | {
7 | public static void Main(string[] args)
8 | {
9 | Console.WriteLine("hello");
10 | Console.ReadKey();
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Wasabi Roslyn Generator")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Fog Creek Software")]
12 | [assembly: AssemblyProduct("FogCreek.Wasabi")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("924c31fc-4c89-41a1-ae8c-f4697d688ffa")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | [assembly: AssemblyVersion("1.0.0.0")]
33 | [assembly: AssemblyFileVersion("1.0.0.0")]
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Wasabi RoslynGenerator
2 |
3 | This is the very back end of the Wasabi-to-C# compiler from Fog Creek Software.
4 | It converts a Wasabi abstract syntax tree (AST) into C# code.
5 |
6 | The CLR importer, lexer, parser, interpreter, type checker, language runtime, JavaScript generator,
7 | and other components of Wasabi are missing.
8 |
9 | It is intended to be used as an example for how to write a C# generator using Microsoft Roslyn.
10 |
11 | Build the solution in Visual Studio, then run `.\Example\bin\Debug\Example.exe` from the root of the repository.
12 |
13 | A very tiny program will be generated in `was_out`.
14 |
--------------------------------------------------------------------------------
/RoslynExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using Microsoft.CodeAnalysis.CSharp;
3 | using Microsoft.CodeAnalysis.CSharp.Syntax;
4 | using System;
5 |
6 | namespace FogCreek.Wasabi.CodeGenerators
7 | {
8 | static class RoslynExtensions
9 | {
10 | public static TypeDeclarationSyntax WithBaseList(this TypeDeclarationSyntax node, BaseListSyntax list)
11 | {
12 | switch (node.Kind())
13 | {
14 | case SyntaxKind.ClassDeclaration:
15 | return ((ClassDeclarationSyntax)node).WithBaseList(list);
16 | case SyntaxKind.InterfaceDeclaration:
17 | return ((InterfaceDeclarationSyntax)node).WithBaseList(list);
18 | case SyntaxKind.StructDeclaration:
19 | return ((StructDeclarationSyntax)node).WithBaseList(list);
20 | }
21 | throw new NotImplementedException("WithBaseList " + node.Kind().ToString());
22 | }
23 |
24 | public static TypeDeclarationSyntax WithModifiers(this TypeDeclarationSyntax node, SyntaxTokenList modifiers)
25 | {
26 | switch (node.Kind())
27 | {
28 | case SyntaxKind.ClassDeclaration:
29 | return ((ClassDeclarationSyntax)node).WithModifiers(modifiers);
30 | case SyntaxKind.InterfaceDeclaration:
31 | return ((InterfaceDeclarationSyntax)node).WithModifiers(modifiers);
32 | case SyntaxKind.StructDeclaration:
33 | return ((StructDeclarationSyntax)node).WithModifiers(modifiers);
34 | }
35 | throw new NotImplementedException("WithModifiers " + node.Kind().ToString());
36 | }
37 |
38 | public static BaseMethodDeclarationSyntax WithModifiers(this BaseMethodDeclarationSyntax node, SyntaxTokenList modifiers)
39 | {
40 | switch (node.Kind())
41 | {
42 | case SyntaxKind.OperatorDeclaration:
43 | case SyntaxKind.ConversionOperatorDeclaration:
44 | throw new NotImplementedException("Wasabi doesn't have operators");
45 | case SyntaxKind.MethodDeclaration:
46 | return ((MethodDeclarationSyntax)node).WithModifiers(modifiers);
47 | case SyntaxKind.ConstructorDeclaration:
48 | return ((ConstructorDeclarationSyntax)node).WithModifiers(modifiers);
49 | case SyntaxKind.DestructorDeclaration:
50 | return ((DestructorDeclarationSyntax)node).WithModifiers(modifiers);
51 | }
52 | throw new NotImplementedException("WithModifiers " + node.Kind().ToString());
53 | }
54 |
55 | public static BasePropertyDeclarationSyntax WithModifiers(this BasePropertyDeclarationSyntax node, SyntaxTokenList modifiers)
56 | {
57 | switch (node.Kind())
58 | {
59 | case SyntaxKind.IndexerDeclaration:
60 | return ((IndexerDeclarationSyntax)node).WithModifiers(modifiers);
61 | case SyntaxKind.PropertyDeclaration:
62 | return (((PropertyDeclarationSyntax)node)).WithModifiers(modifiers);
63 | }
64 | throw new NotImplementedException("WithModifiers " + node.Kind().ToString());
65 | }
66 |
67 | public static BasePropertyDeclarationSyntax WithExplicitInterfaceSpecifier(this BasePropertyDeclarationSyntax node, ExplicitInterfaceSpecifierSyntax syntax)
68 | {
69 | switch (node.Kind())
70 | {
71 | case SyntaxKind.IndexerDeclaration:
72 | return ((IndexerDeclarationSyntax)node).WithExplicitInterfaceSpecifier(syntax);
73 | case SyntaxKind.PropertyDeclaration:
74 | return (((PropertyDeclarationSyntax)node)).WithExplicitInterfaceSpecifier(syntax);
75 | }
76 | throw new NotImplementedException("WithExplicitInterfaceSpecifier " + node.Kind().ToString());
77 | }
78 |
79 | public static BasePropertyDeclarationSyntax WithAccessorList(this BasePropertyDeclarationSyntax node, AccessorListSyntax accessorList)
80 | {
81 | switch (node.Kind())
82 | {
83 | case SyntaxKind.IndexerDeclaration:
84 | return ((IndexerDeclarationSyntax)node).WithAccessorList(accessorList);
85 | case SyntaxKind.PropertyDeclaration:
86 | return (((PropertyDeclarationSyntax)node)).WithAccessorList(accessorList);
87 | }
88 | throw new NotImplementedException();
89 | }
90 |
91 | public static TypeDeclarationSyntax AddMember(this TypeDeclarationSyntax node, MemberDeclarationSyntax member)
92 | {
93 | return node.WithMembers(node.Members.Add(member));
94 | }
95 |
96 | public static TypeDeclarationSyntax WithMembers(this TypeDeclarationSyntax node, SyntaxList members)
97 | {
98 | switch (node.Kind())
99 | {
100 | case SyntaxKind.ClassDeclaration:
101 | return ((ClassDeclarationSyntax)node).WithMembers(members);
102 | case SyntaxKind.InterfaceDeclaration:
103 | return ((InterfaceDeclarationSyntax)node).WithMembers(members);
104 | case SyntaxKind.StructDeclaration:
105 | return ((StructDeclarationSyntax)node).WithMembers(members);
106 | }
107 | throw new NotImplementedException("WithMembers " + node.Kind().ToString());
108 | }
109 |
110 | public static TypeDeclarationSyntax WithAttributeLists(this TypeDeclarationSyntax node, SyntaxList attributes)
111 | {
112 | switch (node.Kind())
113 | {
114 | case SyntaxKind.ClassDeclaration:
115 | return ((ClassDeclarationSyntax)node).WithAttributeLists(attributes);
116 | case SyntaxKind.InterfaceDeclaration:
117 | return ((InterfaceDeclarationSyntax)node).WithAttributeLists(attributes);
118 | case SyntaxKind.StructDeclaration:
119 | return ((StructDeclarationSyntax)node).WithAttributeLists(attributes);
120 | }
121 |
122 | throw new NotImplementedException("WithAttributeLists " + node.Kind().ToString());
123 | }
124 |
125 | public static BaseMethodDeclarationSyntax WithAttributeLists(this BaseMethodDeclarationSyntax node, SyntaxList attributes)
126 | {
127 | switch (node.Kind())
128 | {
129 | case SyntaxKind.OperatorDeclaration:
130 | case SyntaxKind.ConversionOperatorDeclaration:
131 | throw new NotImplementedException("Wasabi doesn't have operators");
132 | case SyntaxKind.MethodDeclaration:
133 | return ((MethodDeclarationSyntax)node).WithAttributeLists(attributes);
134 | case SyntaxKind.ConstructorDeclaration:
135 | return ((ConstructorDeclarationSyntax)node).WithAttributeLists(attributes);
136 | case SyntaxKind.DestructorDeclaration:
137 | return ((DestructorDeclarationSyntax)node).WithAttributeLists(attributes);
138 | }
139 |
140 | throw new NotImplementedException("WithAttributeLists " + node.Kind().ToString());
141 | }
142 |
143 | public static BaseMethodDeclarationSyntax WithParameterList(this BaseMethodDeclarationSyntax method, ParameterListSyntax pls)
144 | {
145 | switch (method.Kind())
146 | {
147 | case SyntaxKind.OperatorDeclaration:
148 | case SyntaxKind.ConversionOperatorDeclaration:
149 | throw new NotImplementedException("Wasabi doesn't have operators");
150 | case SyntaxKind.MethodDeclaration:
151 | return ((MethodDeclarationSyntax)method).WithParameterList(pls);
152 | case SyntaxKind.ConstructorDeclaration:
153 | return ((ConstructorDeclarationSyntax)method).WithParameterList(pls);
154 | case SyntaxKind.DestructorDeclaration:
155 | return ((DestructorDeclarationSyntax)method).WithParameterList(pls);
156 | }
157 |
158 | throw new NotImplementedException("WithParameterList " + method.Kind().ToString());
159 | }
160 |
161 | public static BaseMethodDeclarationSyntax WithReturnType(this BaseMethodDeclarationSyntax method, TypeSyntax type)
162 | {
163 | switch (method.Kind())
164 | {
165 | case SyntaxKind.OperatorDeclaration:
166 | case SyntaxKind.ConversionOperatorDeclaration:
167 | throw new NotImplementedException("Wasabi doesn't have operators");
168 | case SyntaxKind.MethodDeclaration:
169 | return ((MethodDeclarationSyntax)method).WithReturnType(type);
170 | case SyntaxKind.ConstructorDeclaration:
171 | throw new InvalidOperationException("Constructors don't have return type");
172 | case SyntaxKind.DestructorDeclaration:
173 | throw new InvalidOperationException("Destructors don't have return type");
174 | }
175 |
176 | throw new NotImplementedException("WithReturnType " + method.Kind().ToString());
177 | }
178 |
179 |
180 | public static BaseMethodDeclarationSyntax WithBody(this BaseMethodDeclarationSyntax method, BlockSyntax body)
181 | {
182 | switch (method.Kind())
183 | {
184 | case SyntaxKind.OperatorDeclaration:
185 | case SyntaxKind.ConversionOperatorDeclaration:
186 | throw new NotImplementedException("Wasabi doesn't have operators");
187 | case SyntaxKind.MethodDeclaration:
188 | return ((MethodDeclarationSyntax)method).WithBody(body);
189 | case SyntaxKind.ConstructorDeclaration:
190 | return ((ConstructorDeclarationSyntax)method).WithBody(body);
191 | case SyntaxKind.DestructorDeclaration:
192 | return ((DestructorDeclarationSyntax)method).WithBody(body);
193 | }
194 |
195 | throw new NotImplementedException("WithBody " + method.Kind().ToString());
196 | }
197 | }
198 | }
199 |
--------------------------------------------------------------------------------
/WasabiRoslynGenerator.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.31101.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WasabiRoslynGenerator", "WasabiRoslynGenerator.csproj", "{19DFAE1F-FB84-4771-B6D7-F4526875A6E1}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example", "Example\Example.csproj", "{C16DB98C-655F-493E-8751-9AC8A3ACC6F2}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {19DFAE1F-FB84-4771-B6D7-F4526875A6E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {19DFAE1F-FB84-4771-B6D7-F4526875A6E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {19DFAE1F-FB84-4771-B6D7-F4526875A6E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {19DFAE1F-FB84-4771-B6D7-F4526875A6E1}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {C16DB98C-655F-493E-8751-9AC8A3ACC6F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {C16DB98C-655F-493E-8751-9AC8A3ACC6F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {C16DB98C-655F-493E-8751-9AC8A3ACC6F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {C16DB98C-655F-493E-8751-9AC8A3ACC6F2}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/was_out/.gitignore:
--------------------------------------------------------------------------------
1 | *.cs
2 |
--------------------------------------------------------------------------------