/snippets/VS2010/Nemerle.Compiler.Utils/CodeDom/NemerleCodeParserBase.n
http://github.com/xxVisorxx/nemerle · Unknown · 786 lines · 647 code · 139 blank · 0 comment · 0 complexity · c75049fc43cb2906f678050d06b8b7a2 MD5 · raw file
- using System;
- using System.IO;
- using System.Collections;
- using System.Collections.Generic;
- using System.CodeDom;
- using System.CodeDom.Compiler;
- using System.ComponentModel.Design.Serialization;
- using System.Diagnostics;
- using System.Drawing;
- using System.Reflection;
-
- using Nemerle.Assertions;
- using Nemerle.Collections;
- using Nemerle.Compiler;
- using Nemerle.Compiler.Parsetree;
- using Nemerle.Compiler.Typedtree;
- using Nemerle.Completion2;
- using Nemerle.Imperative;
- using Nemerle.Text;
- using Nemerle.Utility;
-
- using System.CodeDom.CodeBinaryOperatorType;
-
- namespace Nemerle.Compiler.Utils
- {
- public class NemerleCodeParserBase
- {
- // now needed only for AsObject
- protected mutable _manager : ManagerClass;
-
- protected virtual ToCodeNamespace(ns : NamespaceTree.Node) : CodeNamespace
- {
- CodeNamespace(ns.GetDisplayName());
- }
-
- protected virtual ToCodeTypeDelegate(del : TopDeclaration.Delegate) : CodeTypeDelegate
- {
- def ty = CodeTypeDelegate(del.Name);
-
- ty.ReturnType = ToCodeTypeReference(del.header.ParsedReturnType);
- ty.Parameters.AddRange(del.header.ParsedParameters.Map(ToCodeParameterDeclarationExpression).NToArray());
-
- ty;
- }
-
- protected virtual ToCodeTypeDeclaration(vrt : TopDeclaration.Variant) : CodeTypeDeclaration
- {
- def ty = CodeTypeDeclaration(vrt.Name);
-
- ty.IsClass = true;
- ty.IsInterface = false;
- ty.BaseTypes.AddRange(vrt.t_extends.Map(ToCodeTypeReference).NToArray());
- ty.TypeParameters.AddRange(ToCodeTypeParameters(vrt.typarms).NToArray());
- ty.Members.AddRange(vrt.decls.Map(ToCodeTypeMember).NToArray());
-
- ty.UserData["Nemerle.TopDeclaration"] = "Variant";
-
- ty;
- }
-
- protected virtual ToCodeTypeDeclaration(vrto : TopDeclaration.VariantOption) : CodeTypeDeclaration
- {
- def ty = CodeTypeDeclaration(vrto.Name);
-
- ty.IsClass = true;
- ty.IsInterface = false;
- //ty.BaseTypes.AddRange(vrto.t_extends.Map(ToCodeTypeReference).NToArray());
- //ty.TypeParameters.AddRange(ToCodeTypeParameters(vrto.typarms).NToArray());
- ty.Members.AddRange(vrto.decls.Map(ToCodeTypeMember).NToArray());
-
- ty.UserData["Nemerle.TopDeclaration"] = "VariantOption";
-
- ty;
- }
-
- protected virtual ToCodeTypeDeclaration(enm : TopDeclaration.Enum) : CodeTypeDeclaration
- {
- def ty = CodeTypeDeclaration(enm.Name);
- ty.IsClass = false;
- ty.IsEnum = true;
- ty.BaseTypes.AddRange(enm.t_extends.Map(ToCodeTypeReference).NToArray());
- ty.TypeParameters.AddRange(ToCodeTypeParameters(enm.typarms).NToArray());
- ty.Members.AddRange(enm.decls.Map(ToCodeTypeMember).NToArray());
- ty;
- }
-
- protected virtual ToCodeTypeDeclaration(ifs : TopDeclaration.Interface) : CodeTypeDeclaration
- {
- def ty = CodeTypeDeclaration(ifs.Name);
- ty.IsClass = false;
- ty.IsInterface = true;
- ty.BaseTypes.AddRange(ifs.t_extends.Map(ToCodeTypeReference).NToArray());
- ty.TypeParameters.AddRange(ToCodeTypeParameters(ifs.typarms).NToArray());
- ty.Members.AddRange(ifs.methods.Map(ToCodeTypeMember).NToArray());
- ty;
- }
-
- protected virtual ToCodeTypeDeclaration(cls : TopDeclaration.Class) : CodeTypeDeclaration
- {
- def ty = CodeTypeDeclaration(cls.Name);
-
- when(cls.Attributes %&& NemerleAttributes.Struct)
- {
- ty.IsClass = false;
- ty.IsStruct = true;
- }
-
- ty.BaseTypes.AddRange(cls.t_extends.Map(ToCodeTypeReference).NToArray());
- ty.TypeParameters.AddRange(ToCodeTypeParameters(cls.typarms).NToArray());
- ty.Members.AddRange(cls.decls.Map(ToCodeTypeMember).NToArray());
- ty;
- }
-
- private ToCodeTypeReference(typeName : string) : CodeTypeReference
- {
- CodeTypeReference(typeName);
- }
-
- protected virtual ToCodeTypeReference(expr : PExpr) : CodeTypeReference
- {
- ToCodeTypeReference(expr.ToString());
- }
-
- protected virtual ToCodeTypeParameter(tyvar : Splicable) : CodeTypeParameter
- {
- CodeTypeParameter(tyvar.GetName().Id);
- }
-
- protected virtual ToCodeTypeParameters(typarms : Typarms) : list [CodeTypeParameter]
- {
- def toCodeTypeParameter(tyvar : Splicable) : CodeTypeParameter
- {
- def tyParm = ToCodeTypeParameter(tyvar);
- typarms.constraints
- .Filter(c => c.tyvar.Equals(tyvar))
- .Iter (c => _ = tyParm.Constraints.Add(ToCodeTypeReference(c.ty)));
- tyParm;
- }
-
- typarms.tyvars.Map(toCodeTypeParameter);
- }
-
- protected virtual ToMemberAttributes(attrs : NemerleAttributes) : MemberAttributes
- {
- mutable memberAttrs: MemberAttributes;
-
- when(attrs %&& NemerleAttributes.Static) memberAttrs |= MemberAttributes.Static;
- when(attrs %&& NemerleAttributes.Public) memberAttrs |= MemberAttributes.Public;
- when(attrs %&& NemerleAttributes.Private) memberAttrs |= MemberAttributes.Private;
-
- if(attrs %&& NemerleAttributes.Internal && attrs %&& NemerleAttributes.Protected)
- memberAttrs |= MemberAttributes.FamilyOrAssembly
- else
- {
- when(attrs %&& NemerleAttributes.Internal) memberAttrs |= MemberAttributes.Assembly;
- when(attrs %&& NemerleAttributes.Protected) memberAttrs |= MemberAttributes.Family;
- }
-
- when(attrs %&& NemerleAttributes.New) memberAttrs |= MemberAttributes.New;
- when(attrs %&& NemerleAttributes.Override) memberAttrs |= MemberAttributes.Override;
- when(attrs %&& NemerleAttributes.Sealed) memberAttrs |= MemberAttributes.Final;
-
- memberAttrs;
- }
-
- protected virtual ToCodeEnumOption(opt : ClassMember.EnumOption) : CodeMemberField
- {
- def ext = (opt.DefinedIn :> TopDeclaration.Enum).t_extends;
-
- def typeRef =
- if(ext.Length>0)
- ToCodeTypeReference(ext.Head);
- else
- ToCodeTypeReference("int");
-
- CodeMemberField(typeRef, opt.Name);
- }
-
- protected virtual ToCodeMemberField(field : ClassMember.Field) : CodeMemberField
- {
- CodeMemberField (ToCodeTypeReference (field.ty), field.Name);
- }
-
- protected virtual ToCodeMemberMethod(func : ClassMember.Function) : CodeMemberMethod
- {
- def codeMethod =
- match(func.Name)
- {
- | ".ctor" => CodeConstructor()
- | ".cctor" => CodeTypeConstructor()
- | "Main" when func.Attributes %&& NemerleAttributes.Static
- => CodeEntryPointMethod()
- | _ => CodeMemberMethod()
- };
-
- codeMethod.Name = func.Name;
- codeMethod.ReturnType = ToCodeTypeReference(func.header.ReturnType);
- //TODO: codeMethod.ReturnTypeCustomAttributes.AddRange(???.NToArray());
- codeMethod.Parameters.AddRange(func.header.Parameters.Map(ToCodeParameterDeclarationExpression).NToArray());
- codeMethod.ImplementationTypes.AddRange(func.implemented.Map(ToCodeTypeReference).NToArray());
- //TODO: codeMethod.PrivateImplementationType = ???
- codeMethod.TypeParameters.AddRange(ToCodeTypeParameters(func.header.TypeParameters).NToArray());
- codeMethod.Statements.AddRange(ToStatements(func.Body).NToArray());
-
- codeMethod;
- }
-
- protected virtual ToCodeParameterDeclarationExpression(parm : Parsetree.PParameter) : CodeParameterDeclarationExpression
- {
- def codeParam = CodeParameterDeclarationExpression(ToCodeTypeReference(parm.Type), parm.Name);
- codeParam.CustomAttributes.AddRange(parm.modifiers.GetCustomAttributes().Map(ToCodeAttributeDeclaration).NToArray());
- //codeParam.Direction = ???
- codeParam;
- }
-
- protected virtual ToCodeMemberProperty(prop : ClassMember.Property) : CodeMemberProperty
- {
- def codeProperty = CodeMemberProperty();
- codeProperty.Name = prop.Name;
- //TODO: codeProperty.ImplementationTypes.AddRange(???(ToCodeTypeReference).NToArray());
- //TODO: codeProperty.PrivateImplementationType = ???
- //TODO: codeProperty.Parameters = ???
- match (prop.getter)
- {
- | Some (m) => codeProperty.GetStatements.AddRange(ToStatements(m.Body).NToArray());
- | None => ()
- }
-
- match (prop.setter)
- {
- | Some (m) => codeProperty.SetStatements.AddRange(ToStatements(m.Body).NToArray());
- | None => ()
- }
-
- codeProperty;
- }
-
- protected virtual ToCodeMemberEvent(evt : ClassMember.Event) : CodeMemberEvent
- {
- def codeEvent = CodeMemberEvent();
- codeEvent.Name = evt.Name;
- codeEvent.Type = ToCodeTypeReference(evt.ty);
- //TODO: codeProperty.ImplementationTypes.AddRange(???(ToCodeTypeReference).NToArray());
- //TODO: codeProperty.PrivateImplementationType = ???
-
- codeEvent;
- }
-
- protected virtual ToCodeTypeMember(member : ClassMember) : CodeTypeMember
- {
- def codeMember =
- match (member)
- {
- | ClassMember.TypeDeclaration as tyDecl
- when tyDecl.td is TopDeclaration.Class => ToCodeTypeDeclaration(tyDecl.td :> TopDeclaration.Class);
- | ClassMember.TypeDeclaration as tyDecl
- when tyDecl.td is TopDeclaration.Variant => ToCodeTypeDeclaration(tyDecl.td :> TopDeclaration.Variant);
- | ClassMember.TypeDeclaration as tyDecl
- when tyDecl.td is TopDeclaration.VariantOption => ToCodeTypeDeclaration(tyDecl.td :> TopDeclaration.VariantOption);
- | ClassMember.TypeDeclaration as tyDecl
- when tyDecl.td is TopDeclaration.Delegate => ToCodeTypeDelegate(tyDecl.td :> TopDeclaration.Delegate);
- | ClassMember.Field as field => ToCodeMemberField(field);
- | ClassMember.Function as func => ToCodeMemberMethod(func);
- | ClassMember.Property as prop => ToCodeMemberProperty(prop);
- | ClassMember.Event as evt => ToCodeMemberEvent(evt);
- | ClassMember.EnumOption as enm => ToCodeEnumOption(enm);
-
- | _ => throw NotSupportedException($"$member not supported");
- }
-
- when(member.modifiers != null)
- {//member.modifiers == null for TopDeclaration.Variant
- codeMember.Attributes = ToMemberAttributes (member.Attributes);
- codeMember.CustomAttributes.AddRange(member.modifiers.GetCustomAttributes().Map(ToCodeAttributeDeclaration).NToArray());
- }
-
- codeMember.UserData["Member"] = member;
-
- codeMember;
- }
-
- protected virtual ToCodeAttributeDeclaration(attr : PExpr) : CodeAttributeDeclaration
- {
- CodeAttributeDeclaration(ToCodeTypeReference(attr));
- }
-
- protected ProcessTypeDeclaration(typeDecl : TopDeclaration) : CodeTypeDeclaration
- {
- match(typeDecl)
- {
- | TopDeclaration.Class as typeDecl => CreateClass(typeDecl)
- | _ =>
- throw NotImplementedException("Non class top declarations aren't supported yet")
- }
- }
-
- protected CreateClass(cls : TopDeclaration.Class) : CodeTypeDeclaration
- {
- // creates class declaration
- def classDecl = CodeTypeDeclaration(cls.Name);
- classDecl.Attributes = CodeDomHelper.GetMemberAttributes(cls.Attributes);
- classDecl.TypeAttributes = CodeDomHelper.GetTypeAttributes(cls.Attributes);
- def typeBuilder = cls.TypeBuilder;
- assert(typeBuilder != null);
-
- foreach (baseType in typeBuilder.GetDirectSuperTypes())
- _ = classDecl.BaseTypes.Add(ToTypeRef(baseType));
-
- classDecl.IsClass = true;
-
- // sets class access mofifiers
- classDecl.IsPartial = CodeDomHelper.IsPartial(cls.Attributes);
-
- // Set type parameters. will it work?
- //VladD2: ?????, ??? ???? ??? ?? ??? ?? ?????.
- //foreach (t in cls.typarms.tyvars)
- // _ = classDecl.TypeParameters.Add(CodeTypeParameter(t.ToString()));
-
- foreach (part is TopDeclaration.Class in typeBuilder.AstParts)
- ProcessClassPart(classDecl, part);
-
- classDecl.UserData["Name"] = cls.Name;
- classDecl.UserData["Member"] = cls;
-
- classDecl
- }
-
- protected virtual ProcessClassPart(classDecl : CodeTypeDeclaration, part : TopDeclaration.Class) : void
- {
- // TODO: Seems like comments went away
- //classDecl.Comments = CodeCommentStatement();
-
- // TODO: Figure out how to parse CustomAttributes
- //classDecl.CustomAttributes = cls.GetModifiers().GetCustomAttributes();
-
- ProcessClassMembers(part.GetMembers(), classDecl);
-
- //TODO: adds usings directives
-
- //AddToCodeNamespace(cls, codeClass);
-
- //TODO: Add Location ?
- }
-
- // needed cause we may want to override it in derived classes
- protected virtual ProcessClassMembers(members : list[ClassMember], classDecl : CodeTypeDeclaration) : void
- {
- foreach (m in members)
- {
- def codeTypeMember : CodeTypeMember =
- match (m : ClassMember)
- {
- | TypeDeclaration(td) => ProcessTypeDeclaration(td)
- | Field as field => CreateField(field)
- | Property as prop => CreateProperty(prop)
- | Event as vnt => CreateEvent(vnt)
- | Function as func => CreateMethod(func)
- | EnumOption => assert(false, "ClassMember.EnumOption not supported yet");
- };
-
- // TODO: Seems like comments went away
- //memberDecl.Comments = CodeCommentStatement();
-
- // TODO: Figure out how to parse CustomAttributes
- //memberDecl.CustomAttributes = member.GetModifiers().GetCustomAttributes();
-
- //// Add Location
- //memberDecl.UserData.Add(typeof(Location), member.Location);
-
- def loc = m.BodyOpenTokenLocation;
- codeTypeMember.UserData[typeof(Point)] = Point(loc.EndColumn, loc.EndLine);
- codeTypeMember.UserData["Name"] = m.Name;
- codeTypeMember.UserData["Member"] = m;
- codeTypeMember.Name = m.Name;
- _ = classDecl.Members.Add(codeTypeMember);
- }
- }
-
- protected virtual CreateField(field : ClassMember.Field) : CodeMemberField
- {
- // GetFieldInfo() doesn't work
- //def fieldDecl = CodeMemberField(field.GetFieldInfo().FieldType, field.Name);
-
- Debug.Print($"CreateField: from field $field");
-
- // TODO: VladD2: Using of GetSystemType() is bad idea!
- def fieldDecl = CodeMemberField(ToTypeRef(field.ty), field.Name);
-
- fieldDecl.Attributes = CodeDomHelper.GetMemberAttributes(field.Attributes, true);
-
- when (field.Initializer != null)
- fieldDecl.InitExpression = ToExpression(field.Initializer);
-
- fieldDecl
- }
-
- protected virtual CreateProperty(prop : ClassMember.Property) : CodeMemberProperty
- {
- Debug.Print($"CreateProperty: from $prop");
-
- def result = CodeMemberProperty();
- result.Attributes = CodeDomHelper.GetMemberAttributes(prop.Attributes);
- result.Name = prop.Name;
-
- when(prop.getter is Some(get))
- {
- result.HasGet = true;
- result.Type = ToTypeRef(get.header.ReturnType);
- _ = result.GetStatements.AddRange(ToStatements(get.Body).NToArray())
- }
-
- when(prop.setter is Some(set))
- {
- result.HasSet = true;
- result.Type = ToTypeRef(set.header.ReturnType);
- _ = result.SetStatements.AddRange(ToStatements(set.Body).NToArray())
- }
-
- result
- }
-
- protected virtual CreateEvent(evt : ClassMember.Event) : CodeMemberEvent
- {
- def eventDecl = CodeMemberEvent();
- eventDecl.Attributes = CodeDomHelper.GetMemberAttributes(evt.Attributes);
- eventDecl.Name = evt.Name;
- eventDecl.Type = ToTypeRef(evt.ty);
- eventDecl
- }
-
- protected virtual CreateMethod(method : ClassMember.Function) : CodeMemberMethod
- {
- Debug.Print($"CreateMethod : from $method");
-
- def methodDecl : CodeMemberMethod =
- match(method.Name)
- {
- | ".ctor" when method.Attributes %&& NemerleAttributes.Static => CodeTypeConstructor()
- | ".ctor" => CodeConstructor()
- | "Main" when method.Attributes %&& NemerleAttributes.Static => CodeEntryPointMethod()
- | _ => CodeMemberMethod()
- };
-
- methodDecl.Attributes = CodeDomHelper.GetMemberAttributes(method.Attributes, false);
-
- //TODO: methodDecl.ImplementationTypes - how to get that
-
- //methodDecl.Parameters
- foreach (p in method.header.Parameters)
- _ = methodDecl.Parameters.Add(CodeParameterDeclarationExpression(ToTypeRef(p.Type), p.Name));
-
- //TODO: methodDecl.PrivateImplementationType ?
-
- methodDecl.ReturnType = ToTypeRef(method.header.ReturnType);
-
- // methodDecl.TypeParameters , TODO: check if it actually works
- foreach (tp in method.header.TypeParameters.tyvars)
- _ = methodDecl.TypeParameters.Add(CodeTypeParameter(tp.ToString()));
-
- //_currentMethod = method;
- method.Builder.EnsureCompiled(); // we need PExpr & TExpr
-
- try
- {
- methodDecl.Statements.AddRange(ToStatements(method.Builder.BodyParsed).NToArray());
- }
- catch { | _ => () }
-
- //Debug.Print($" method.BodyTyped.Location (col = $(method.BodyTyped.Location.Column), line = $(method.BodyTyped.Location.Line))");
-
- methodDecl
- }
-
- ToTypeRefExpression(typeInfo : Nemerle.Compiler.TypeInfo, typeParaams : list[TypeVar]) : CodeTypeReferenceExpression
- {
- CodeTypeReferenceExpression(ToTypeRef(typeInfo, typeParaams))
- }
-
- ToTypeRefExpression(tyVar : TypeVar) : CodeTypeReferenceExpression
- {
- CodeTypeReferenceExpression(ToTypeRef(tyVar))
- }
-
- ToTypeRef(tyVar : PExpr) : CodeTypeReference
- {
- def cnvToCsTy(t : object)
- {
- t.ToString().Replace(".[", "<").Replace("[", "<").Replace("]", ">")
- }
- match (tyVar.TypedObject)
- {
- | t is TypeVar => ToTypeRef(t)
- | null => CodeTypeReference(cnvToCsTy(tyVar))
- | t => CodeTypeReference(cnvToCsTy(t))
- }
- }
-
- ToTypeRef(tyVar : TypeVar) : CodeTypeReference
- {
- _manager.Solver.PushState();
- try
- {
- def ty = tyVar.Fix();
-
- if (ty.IsFixed)
- {
- def makeTypeArgs(args) { args.MapToArray(ToTypeRef) }
-
- match (ty)
- {
- | Class(tycon, args) => ToTypeRef(tycon, args)
- | StaticTypeVarRef(tyvar) => CodeTypeReference(tyvar.Name)
- | Fun(_from, _to) => CodeTypeReference(typeof(object)) // HACK: Not supported by C#
- | Tuple(args) =>
- CodeTypeReference("Nemerle.Builtins.Tuple", makeTypeArgs(args))
- | Array(tyVar, rank) => CodeTypeReference(ToTypeRef(tyVar), rank)
- | Void => CodeTypeReference(typeof(void))
- | Ref(_tyVar)
- | Out(_tyVar) => throw ApplicationException("Ref/Out not supported")
- | Intersection(_types) => CodeTypeReference(typeof(object))
- }
- }
- else CodeTypeReference(typeof(object))
- }
- finally { _manager.Solver.PopState(); }
- }
-
- ToTypeRef(typeInfo : Nemerle.Compiler.TypeInfo, typeParams : list[TypeVar]) : CodeTypeReference
- {
- //Debug.Assert(typeInfo.TyparmsCount == 0, "typeInfo.TyparmsCount == 0, value is $(typeInfo.TyparmsCount)"); // TODO: Add support for type parameters!
- //Debug.Assert(typeParams.IsEmpty, $"typeParams.IsEmpty, value is $(typeParams.ToString())");
-
- if (typeInfo.SystemType != null)
- CodeTypeReference(typeInfo.SystemType.FullName, typeParams.Map(ToTypeRef).NToArray());
- else
- CodeTypeReference(typeInfo.FullName, typeParams.Map(ToTypeRef).NToArray());
- }
-
- protected virtual ToExpression(expr : PExpr) : CodeExpression
- {
- match (expr)
- {
- | <[ $expr1 && $expr2 ]> with op = BooleanAnd
- | <[ $expr1 || $expr2 ]> with op = BooleanOr
- | <[ $expr1 != $expr2 ]> with op = IdentityInequality
- | <[ $expr1 == $expr2 ]> with op = IdentityEquality
- | <[ $expr1 & $expr2 ]> with op = BitwiseAnd
- | <[ $expr1 | $expr2 ]> with op = BitwiseOr
- | <[ $expr1 + $expr2 ]> with op = Add
- | <[ $expr1 - $expr2 ]> with op = Subtract
- | <[ $expr1 / $expr2 ]> with op = Divide
- | <[ $expr1 * $expr2 ]> with op = Multiply =>
- CodeBinaryOperatorExpression(ToExpression(expr1), op, ToExpression(expr2))
-
- | <[ array[..$parms] ]> as ary =>
- def tExpr = ary.TypedObject :> TExpr;
- match (tExpr)
- {
- | TExpr.Array(_args, dimensions) =>
- Debug.Assert(dimensions is [_]);
- CodeArrayCreateExpression(
- ToTypeRef(tExpr.FixedType()), parms.MapToArray(ToExpression))
- | _ => NotSupportedExpression(ary)
- }
-
- | <[ $obj.$func(..$parms) ]> as call =>
- match (call.func.TypedObject)
- {
- | TExpr.StaticRef(from, mem, type_parms) when mem.MemberKind == MemberTypes.Constructor =>
- def codeParams = parms.MapToArray(ToExpression);
- CodeObjectCreateExpression(ToTypeRef(from.tycon, type_parms), codeParams);
-
- | te =>
- _ = te;
- CodeMethodInvokeExpression(
- CodeMethodReferenceExpression(ToExpression(obj),
- func.ToString()),
- parms.MapToArray(ToExpression));
- }
-
- | <[ + $expr ]> => ToExpression(expr)
- | <[ - $expr ]> =>
- def result = ToExpression(expr);
- match (result)
- {
- | cde is CodePrimitiveExpression =>
- match (cde.Value)
- {
- | val is int => CodePrimitiveExpression(-val)
- | val is long => CodePrimitiveExpression(-val)
- | val is short => CodePrimitiveExpression(-val)
- | val is decimal => CodePrimitiveExpression(-val)
- | val is double => CodePrimitiveExpression(-val)
- | val is float => CodePrimitiveExpression(-val)
- | _ => CodeBinaryOperatorExpression(CodePrimitiveExpression(0), CodeBinaryOperatorType.Subtract, cde)
- }
- | _ => CodeBinaryOperatorExpression(CodePrimitiveExpression(0), CodeBinaryOperatorType.Subtract, result)
- }
-
- | PExpr.Literal(literal) =>
- match (literal)
- {
- | Void => CodeTypeReferenceExpression("void")
- | Null with val = null : object | String(val) | Float (val) | Double (val)
- | Decimal (val) | Char (val) | Bool (val) => CodePrimitiveExpression(val)
- | Integer(val, is_negative, _treat_as) =>
- def val = val :> long;
- def val = if (is_negative) -val else val;
- def it = _manager.InternalType;
- def res = if (_treat_as.Equals(it.Int32)) CodePrimitiveExpression(val :> int)
- else if (_treat_as.Equals(it.UInt32)) CodePrimitiveExpression(val :> uint)
- else if (_treat_as.Equals(it.Int16)) CodePrimitiveExpression(val :> short)
- else if (_treat_as.Equals(it.UInt16)) CodePrimitiveExpression(val :> ushort)
- else if (_treat_as.Equals(it.SByte)) CodePrimitiveExpression(val :> sbyte)
- else if (_treat_as.Equals(it.Byte)) CodePrimitiveExpression(val :> byte)
- else CodePrimitiveExpression(val);
-
- res
-
- | Enum (_val : Literal.Integer, ty : TypeInfo, field : IField) =>
- CodeFieldReferenceExpression(CodeTypeReferenceExpression(ty.FullName), field.Name)
- }
-
- | <[ $func(..$parms) ]> => // TODO: Add support of ctor's
- match (func.TypedObject)
- {
- | TExpr.StaticRef(from, mem, tParms) when mem.MemberKind == MemberTypes.Constructor =>
- def codeParams = parms.MapToArray(ToExpression);
- CodeObjectCreateExpression(ToTypeRef(from.tycon, tParms), codeParams)
-
- | TExpr.MethodRef(obj = TExpr.This) with codeObj = CodeThisReferenceExpression()
- | TExpr.MethodRef(obj = TExpr.Base) with codeObj = CodeBaseReferenceExpression() =>
- CodeMethodInvokeExpression(
- CodeMethodReferenceExpression(codeObj,
- func.ToString()),
- parms.MapToArray(ToExpression));
-
- | te =>
- _ = te;
- CodeMethodInvokeExpression(
- CodeMethodReferenceExpression(null,
- func.ToString()),
- parms.MapToArray(ToExpression));
- }
-
- | <[ $obj.$field ]> when field.TypedObject is IField =>
- CodeFieldReferenceExpression(ToExpression(obj), field.TypedObject.Name);
-
- | <[ $obj.$prop ]> when prop.TypedObject is IProperty =>
- CodePropertyReferenceExpression(ToExpression(obj), prop.TypedObject.Name);
-
- | <[ $obj.$_ ]> as mem when mem.TypedObject is TExpr =>
- match (mem.TypedObject)
- {
- | TExpr.StaticRef(_from, mem, type_parms) when mem.IsStatic =>
- CodeFieldReferenceExpression(
- ToTypeRefExpression(mem.DeclaringType, type_parms), mem.Name)
-
- | TExpr.MethodRef(_tObj, meth, typeParms, _notvirtual) =>
- CodeMethodReferenceExpression(ToExpression(obj), meth.Name,
- typeParms.MapToArray(param => ToTypeRef(param)))
-
- | TExpr.StaticPropertyRef(from, prop) =>
- CodeFieldReferenceExpression(ToTypeRefExpression(from), prop.Name)
-
- | xxx => //TExpr.StaticPropertyRef
- _ = xxx;
- NotSupportedExpression(expr)
- }
-
- | PExpr.Ref(name) => CodeVariableReferenceExpression(name.ToString())
-
- | <[ $sourceExpr :> $_ ]> =>
- def tExpr = expr.TypedObject :> TExpr.TypeConversion;
- CodeCastExpression(ToTypeRef(tExpr.FixedType()), ToExpression(sourceExpr))
-
- | <[ base ]> => CodeBaseReferenceExpression()
- | <[ this ]> => CodeThisReferenceExpression()
- | <[ typeof($typeExpr) ]> => CodeTypeOfExpression(typeExpr.ToString()) // TODO: Test it
- | null => CodeSnippetExpression("");
- | PExpr.Member(_, _) => // (obj, member)
- //TODO: VladD2: ?????-?? ????. ???? ??? ??????????...
- // sample: obj = System.Drawing, member = Color
- match(_manager.CoreEnv.LookupType(expr.ToString().Split('.').NToList()))
- {
- | Some(ti) => CodeTypeReferenceExpression(ti.FullName);
- | _ => NotSupportedExpression(expr);
- }
-
- | _ => NotSupportedExpression(expr)
- }
- }
-
- NotSupportedExpression(expr : PExpr) : CodeExpression
- {
- def msg = $"[Form Designer]: Not suported expression: '$expr' ($(expr.GetType().Name)). Please, report about this bug.";
- Debug.WriteLine(msg);
- Message.Warning(expr.Location, msg);
- CodeSnippetExpression(expr.ToString())
- }
-
- GetInferredType(expr : PExpr) : CodeTypeReference
- {
- match (expr.TypedObject)
- {
- | tExpr is TExpr => ToTypeRef(tExpr.Type)
- | val is LocalValue => ToTypeRef(val.Type)
- | ty is TypeVar => ToTypeRef(ty)
- | _ => throw NotSupportedException($"can't inferr type for '$expr' expression")
- }
- }
-
- protected ToStatements(expr : PExpr) : IEnumerable[CodeStatement]
- {
- match (expr)
- {
- | PExpr.Sequence(exprs) =>
- foreach (expr in exprs)
- foreach (codeStatement in ToStatements(expr))
- yield codeStatement;
-
- | <[ $expr1 += $expr2 ]> =>
- match (expr1)
- {
- | <[ $obj.$member ]> when member.TypedObject is IEvent =>
- yield CodeAttachEventStatement(ToExpression(obj),
- member.TypedObject.Name, ToExpression(expr2))
-
- | _ =>
- yield CodeAssignStatement(ToExpression(expr1), ToExpression(<[ $expr1 + $expr2 ]>))
- }
-
- | <[ $expr1 -= $expr2 ]> =>
- match (expr1)
- {
- | <[ $obj.$member ]> when member.TypedObject is IEvent =>
- yield CodeRemoveEventStatement(ToExpression(obj),
- member.TypedObject.Name, ToExpression(expr2))
-
- | _ =>
- yield CodeAssignStatement(ToExpression(expr1), ToExpression(<[ $expr1 - $expr2 ]>))
- }
-
- | <[ $target = $source ]> =>
- yield CodeAssignStatement(ToExpression(target), ToExpression(source))
-
- | <[ mutable $expr = $val ]> with isMutable = true
- | <[ def $expr = $val ]> with isMutable = false =>
-
- def (expr, tyRef) =
- match (expr)
- {
- | PExpr.TypeEnforcement(expr, ty) => (expr, GetInferredType(ty))
- | _ => (expr, GetInferredType(expr));
- };
-
-
- def name =
- match (expr)
- {
- | PExpr.Ref(name) => name.Id;
- | _ => throw NotSupportedException($"$expr not supported");
- };
-
- def statement =
- match (val)
- {
- | null => CodeVariableDeclarationStatement(tyRef, name);
- | _ => CodeVariableDeclarationStatement(tyRef, name, ToExpression(val))
- };
-
- statement.UserData["mutable"] = isMutable;
- yield statement;
-
- | <[ when ($cond) $expr ]> =>
- yield CodeConditionStatement(ToExpression(cond), ToStatements(expr).NToArray())
-
- | <[ if ($cond) $trueExpr else $falseExpr ]> =>
- yield CodeConditionStatement(ToExpression(cond),
- ToStatements(trueExpr).NToArray(), ToStatements(falseExpr).NToArray())
-
- | _ => yield CodeExpressionStatement(ToExpression(expr))
- }
- }
- }
- }