[svn] r7186: vs-plugin/trunk/Nemerle.Compiler.Utils: NemerleCodeDomProvider.n NemerleCodeParser.n

akhropov svnadmin at nemerle.org
Mon Jan 1 18:30:51 CET 2007


Log:
add new TExpr-based code parser

Author: akhropov
Date: Mon Jan  1 18:30:28 2007
New Revision: 7186

Added:
   vs-plugin/trunk/Nemerle.Compiler.Utils/NemerleCodeParser.n
Modified:
   vs-plugin/trunk/Nemerle.Compiler.Utils/NemerleCodeDomProvider.n

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/NemerleCodeDomProvider.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/NemerleCodeDomProvider.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/NemerleCodeDomProvider.n	Mon Jan  1 18:30:28 2007
@@ -28,7 +28,7 @@
 #pragma warning restore 618
 
       if (parser == null)
-        CodeDomParser();
+        NemerleCodeParser();
       else
         parser;
     }

Added: vs-plugin/trunk/Nemerle.Compiler.Utils/NemerleCodeParser.n
==============================================================================
--- (empty file)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/NemerleCodeParser.n	Mon Jan  1 18:30:28 2007
@@ -0,0 +1,588 @@
+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;
+
+namespace Nemerle.Compiler.Utils
+{
+  // now CodeDomParser only parses files from Project.CompileUnits
+  // it is not thread-safe at the moment!
+  public class NemerleCodeParser : ICodeParser
+  {
+    // now needed only for AsObject
+    protected mutable _manager : ManagerClass;
+
+          // TODO: do we need to make it type-safe
+    protected mutable _currentMethod : MethodBuilder;
+
+    public this(manager: ManagerClass = null)
+    {
+      _manager = if (manager != null) manager
+                 else ManagerClass.Instance;
+    }
+
+    // AKhropov: TODO
+    public Parse(codeStream: TextReader) : CodeCompileUnit
+    {
+      _ = codeStream;
+      throw NotImplementedException("Psrsing of text files is not implemented!");
+    }
+
+    protected ProcessTypeDeclaration(typeDecl: TypeBuilder) : CodeTypeDeclaration
+    {
+      match(typeDecl.GetTydecl())
+      {
+       | TypeDeclaration.Class  => CreateClass(typeDecl)
+       | _ => 
+          throw NotImplementedException("Non class top declarations aren't supported yet")
+      }
+    }
+
+    protected CreateClass(cls: TypeBuilder) : CodeTypeDeclaration
+    {
+      // creates class declaration
+      def classDecl = CodeTypeDeclaration(cls.Name);
+      
+      classDecl.Attributes = CodeDomHelper.GetMemberAttributes(cls.Attributes);
+      cls.GetDirectSuperTypes().Iter(baseType =>
+        classDecl.BaseTypes.Add(baseType.tycon.FullName));
+
+      // TODO: Seems like comments went away
+      //classDecl.Comments = CodeCommentStatement();
+
+      // TODO: Figure out how to parse CustomAttributes
+      //classDecl.CustomAttributes = cls.GetModifiers().GetCustomAttributes();
+
+      classDecl.IsClass = true;
+
+      // sets class access mofifiers
+      classDecl.IsPartial = CodeDomHelper.IsPartial(cls.Attributes);
+      classDecl.TypeAttributes = CodeDomHelper.GetTypeAttributes(cls.Attributes);
+
+      // Set type parameters
+      // will it work?
+      cls.Typarms.Iter(t => { _ = classDecl.TypeParameters.Add(CodeTypeParameter(t.Name));});
+
+      // adds members
+      Debug.Print("ProcessClassMembers in reversed order");
+      ProcessClassMembers(cls.GetMembers().Reverse(), classDecl);
+      
+      //TODO: adds usings directives
+
+      //AddToNamespace(cls, codeClass);
+
+      //TODO: Add Location ?
+
+      classDecl
+    }
+
+    // needed cause we may want to override it in derived classes
+    protected virtual ProcessClassMembers(members: list[IMember],classDecl: CodeTypeDeclaration) : void
+    {
+      members.Iter(m : IMember =>
+        match(m)
+        {
+          | m is TypeBuilder => {_ = classDecl.Members.Add(CreateClass(m));}
+          //| m is EventBuilder => CreateEvent(m) // TODO
+          //| m is FieldBuilder => CreateField(m) 
+          | m is MemberBuilder => {_ = classDecl.Members.Add(CreateMember(m));}
+          //| m is PropertyBuilder => CreateProperty(m)// TODO
+
+          //| m is NetEvent 
+          //| m is NetProperty
+          //| m is MethodInfo =>
+          | _ =>
+            () //Debug.Print($"Declaration of external member $m ignored");
+          /*| _ => 
+            throw CodeDomSerializerException($"Unknown declaration type: $m of type $(m.GetType().ToString())",
+                                             CodeLinePragma(m.Location.File, m.Location.Line)); 
+          */
+        }
+        //} 
+      );
+    }
+
+    protected virtual CreateMember(member: MemberBuilder) : CodeTypeMember
+    {
+      Debug.Print($"CreateMember : from $member");
+
+      // creates class declaration
+      def memberDecl : CodeTypeMember = 
+        match(member)
+        {
+          //| m is EventBuilder => CreateEvent(m) // TODO
+          | m is FieldBuilder => CreateField(m)
+          | m is MethodBuilder => CreateMethod(m) 
+          //| m is PropertyBuilder => CreateProperty(m) // TODO
+          | _ => 
+            { Debug.WriteLine($"CodeDomParser ignore declaration: $member : $(member.Name)"); null }
+        }
+  
+      memberDecl.Name = member.Name;
+      
+      // performed in CreateField/CreateMethod
+      //memberDecl.Attributes = CodeDomHelper.GetMemberAttributes(member.Attributes);
+      
+      // 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);
+
+      memberDecl
+    }
+
+    protected virtual CreateField(field: FieldBuilder) : CodeMemberField
+    {
+      // GetFieldInfo() doesn't work
+      //def fieldDecl = CodeMemberField(field.GetFieldInfo().FieldType, field.Name);
+
+      Debug.Print($"CreateField: from field $field");
+
+      //def fieldDecl = CodeMemberField(field.Ast.ty.ToString(), field.Name);
+      def fieldDecl = CodeMemberField(field.GetMemType().SystemType, field.Name);
+      
+      fieldDecl.Attributes = CodeDomHelper.GetMemberAttributes(field.Attributes, true);
+
+      /*if (field.IsLiteral)
+        fieldDecl.InitExpression = CodePrimitiveExpression(field.GetValue().AsObject(
+          _manager.InternalType));
+      else */
+
+      // temporary
+      //when (field.IsInitializerPresent)
+      //  fieldDecl.InitExpression = CreateExpression(field.InitializerTyped);
+
+      fieldDecl
+    }
+
+    protected virtual CreateMethod(method: MethodBuilder) : CodeMemberMethod
+    { 
+      Debug.Print($"CreateMethod : from $method");
+
+      def methodDecl : CodeMemberMethod =
+        match(method.GetFunKind())
+        {
+          | FunKind.Constructor => CodeConstructor()
+          | FunKind.StaticConstructor => CodeTypeConstructor()
+          | _ when method.Name == "Main" => CodeEntryPointMethod()
+          | _ when method.Name == ".ctor" =>  // TODO
+            throw CodeDomSerializerException($"Didn't expect that method: $method",
+                                               CodeLinePragma(method.Location.File, method.Location.Line)); 
+            /*
+            if(method.Attributes %&& NemerleAttributes.Static)
+              CodeTypeConstructor();
+            else
+              CodeConstructor();
+            */
+          | _ => CodeMemberMethod()
+        };
+
+      methodDecl.Attributes = CodeDomHelper.GetMemberAttributes(method.Attributes, false);
+
+      //TODO: methodDecl.ImplementationTypes - how to get that
+      
+
+      //methodDecl.Parameters
+      method.GetParameters().Iter(param =>
+          { _ = methodDecl.Parameters.Add(CodeParameterDeclarationExpression(param.SystemType, param.Name)) } 
+     );
+
+      //TODO:  methodDecl.PrivateImplementationType ?
+
+      methodDecl.ReturnType = CodeTypeReference(method.ReturnType.SystemType);
+
+      // methodDecl.TypeParameters , TODO: check if it actually works
+      method.GetHeader().typarms.Iter(typaram =>
+        { _ = methodDecl.TypeParameters.Add(CodeTypeParameter(typaram.Name))}
+     ); 
+
+      // Body , TODO: does this work?
+      //methodDecl.Statements.AddRange(CreateStatements(method.Ast));
+      /*
+      match(method.Ast.body)
+      {
+        | FunBody.Parsed(expr) => 
+          CreateStatements(expr, methodDecl.Statements);
+        | FunBody.Typed(expr) => CreateStatements(expr, methodDecl.Statements);
+        | _                   =>
+          throw InvalidOperationException($"Function body of $method is supposed to be Typed");
+      } 
+      */
+
+      //Debug.Write(method.Ast.body);
+        //.Typed.expr);
+
+     _currentMethod = method;
+
+      match(methodDecl)
+      {
+        | m is CodeConstructor => CreateCtorStatements(m, method.BodyTyped);
+        | _                    => CreateStatements(method.BodyTyped, methodDecl.Statements);
+      }
+
+      Debug.Print($"  method.BodyTyped.Location (col = $(method.BodyTyped.Location.Column), line = $(method.BodyTyped.Location.Line))");
+
+      methodDecl
+    }
+
+    protected CreateParamsArray(parms : list [Parm]) : array[CodeExpression]
+    {
+      | [] => array[CodeSnippetExpression("")]
+      | _  => parms.MapToArray(p => CreateExpression(p.expr));
+    }
+
+    protected CreateCtorStatements(ctor : CodeConstructor, expr : TExpr) : void 
+    {
+      // TODO : now base(..) or this(...) constructor calls are supposed to be the first calls
+      //        in the ctor body. 
+      match(expr)
+      {
+        | TExpr.Sequence(e1,e2) => 
+          { CreateCtorStatements(ctor,e1); CreateStatements(e2,ctor.Statements); }
+        | TExpr.Call(func,parms,_) when (func is TExpr.Base) => 
+          ctor.BaseConstructorArgs.AddRange(CreateParamsArray(parms));
+        | TExpr.Call(func,parms,_) when (func is TExpr.This) => 
+          ctor.ChainedConstructorArgs.AddRange(CreateParamsArray(parms));
+        | _ => 
+          CreateStatements(expr,ctor.Statements); 
+      }
+    }
+
+    protected virtual CreateStatements(expr : TExpr, statements: CodeStatementCollection) : void 
+    {
+      match(expr)
+      {
+        | TExpr.Sequence(e1,e2) => 
+          { CreateStatements(e1,statements); CreateStatements(e2,statements); }
+
+        | TExpr.MacroEnvelope(original,the_macro,_) as expr => // original : Parsetree.PExpr; the_macro : IMacro; expanded : TExpr; }
+          // TODO: may be ignore or make code snippet?
+          Debug.Print($"--Expanding macro $(CodeDomHelper.PrintMacro(the_macro)),\n--- original:$original");
+          ProcessMacroStatements(expr,statements)
+          //CreateStatements(expanded,statements); 
+
+        | TExpr.DefValIn(name,val,body) => // name : LocalValue; val : TExpr; mutable body : TExpr; }
+          _ = statements.Add( CodeVariableDeclarationStatement(name.Type.SystemType, name.Name, CreateExpression(val)) );
+          CreateStatements(body,statements); 
+          
+        | _ => 
+          _ = statements.Add(CreateStatement(expr))
+      }
+    }
+
+    protected virtual ProcessMacroStatements(macroEnvelope : TExpr.MacroEnvelope, statements: CodeStatementCollection) : void
+    {
+      | (TExpr.MacroEnvelope(original,the_macro,expanded),_) => // original : Parsetree.PExpr; the_macro : IMacro; expanded : TExpr; }
+        Debug.Print($"  ProcessMacroStatements ($(the_macro.GetName())) :\n original=$original,\n"
+                    "expanded = $expanded\n");
+        CreateStatements(expanded,statements)
+    }
+
+    protected CreateStatements(expr : TExpr) : array[CodeStatement]
+    {
+      def statements = CodeStatementCollection();
+      CreateStatements(expr,statements);
+      def statementsArray = array(statements.Count);
+      statements.CopyTo(statementsArray, 0);
+      statementsArray
+    }
+
+    protected virtual CreateStatement(expr : TExpr) : CodeStatement 
+    {
+      Debug.Print($"  CreateStatement : from expr of type $(expr.GetType())");
+      
+      match(expr) // TODO: this is temporary
+      {
+      | TExpr.Assign(target,source) => // target : TExpr; source : TExpr; }
+        CodeAssignStatement(CreateExpression(target), CreateExpression(source))
+      
+      | TExpr.Call(func,parms,_) when(parms.Length == 1) =>// mutable func : TExpr; mutable parms : list [Parm]; _ }
+        def s = TryCreateEventAction(func,parms);
+        if (s != null) s else CodeExpressionStatement(CreateExpression(expr))// standard way
+
+      | TExpr.Throw(exn) =>             // exn : TExpr; }
+        CodeThrowExceptionStatement(CreateExpression(exn))
+
+      | TExpr.TryFinally(body,handler) => // body : TExpr; handler : TExpr; }
+        match(body)
+        {
+          | TExpr.Try(body,cases) =>
+            CodeTryCatchFinallyStatement( CreateStatements(body),
+                                          cases.MapToArray( CreateCatchClause(_) ),
+                                          CreateStatements(handler))
+          | _ => 
+            CodeTryCatchFinallyStatement( CreateStatements(body),
+                                          null,
+                                          CreateStatements(handler))
+        }
+            
+
+      | TExpr.Try(body,cases) =>    // body : TExpr; mutable cases : list [Try_case]; }
+        CodeTryCatchFinallyStatement( CreateStatements(body),
+                                      cases.MapToArray( CreateCatchClause(_) ),
+                                      null)
+
+      /*
+      | TExpr.OpCode                // name : string; }
+      */
+      | TExpr.MacroEnvelope as expr => // original : Parsetree.PExpr; the_macro : IMacro; expanded : TExpr; }
+        ProcessMacroStatement(expr)
+
+      | TExpr.If(cond, e_then, e_else) =>  // { cond : TExpr; e_then : TExpr; e_else : TExpr; }
+        CodeConditionStatement(CreateExpression(cond),
+                               CreateStatements(e_then),
+                               CreateStatements(e_else))
+
+      | _ =>
+        CodeExpressionStatement(CreateExpression(expr))
+        /*{ Debug.Print($"Ignored: expr of type $(expr.GetType()) = $expr ");
+          CodeCommentStatement("dummy") }
+        */
+      }
+      
+      //CodeCommentStatement("dummy")
+    }
+
+    protected TryCreateEventAction(func : TExpr, parms : list[Parm]) : CodeStatement
+    {
+      def eventActionAndName(name)
+      {
+        Debug.Print($"Checking for event attachment for $func Name = $name");
+        regexp match(name)
+        {
+          | @"add_(?<name>\w+)" => 
+            Debug.Print($"Looks like we've found an event attachment: $name");
+            ("add",name)
+          
+          | @"remove_(?<name>\w+)" => 
+            Debug.Print($"Looks like we've found an event remove: $name");
+            ("remove",name)
+
+          | _ => 
+            (null,null)
+        }
+      }
+
+      def (objType,obj,(eventAction,eventName)) = match(func)
+      {
+        | TExpr.StaticRef(from,mem,_) when (mem is IMethod) =>
+          (from.SystemType,
+           lazy(CodeTypeReferenceExpression(from.SystemType)),
+           eventActionAndName(mem.Name))
+            
+        // TODO: Are typed events possible?
+        | TExpr.MethodRef(obj,meth,_,_) => // obj : TExpr; meth : IMethod; type_parms : list [TyVar]; _; }
+          (obj.SystemType,
+           lazy(CreateExpression(obj)),
+           eventActionAndName(meth.Name))
+          
+        | _ => (null,null,(null,null))
+      }
+      if (eventAction != null && objType.GetEvent(eventName) != null)
+        if (eventAction == "add")
+          CodeAttachEventStatement(obj, eventName, CreateExpression(parms.Head.expr))
+        else // eventAction == "remove"
+          CodeRemoveEventStatement(obj, eventName, CreateExpression(parms.Head.expr))
+      else null
+    }
+
+    protected virtual ProcessMacroStatement(macroEnvelope : TExpr.MacroEnvelope) : CodeStatement
+    {
+      | (original,the_macro,expanded) => // original : Parsetree.PExpr; the_macro : IMacro; expanded : TExpr; }
+        Debug.Print($"  ProcessMacroStatement ($(the_macro.GetName())) :\n original=$original,\n"
+                    "expanded = $expanded\n");
+        CreateStatement(expanded)
+    }
+
+    protected virtual CreateExpression(expr : TExpr) : CodeExpression
+    {
+      Debug.Print($"  CreateExpression : from expr of type $(expr.GetType())");
+      
+      match(expr) // TODO: this is temporary
+      {
+      | TExpr.StaticRef(from,mem,type_parms) => //{ from : MType.Class; mem : IMember; type_parms : list [TyVar]; }
+        match(mem)
+        {
+          | mem is TypeInfo => 
+            Debug.Print($"TypeInfo of type $(mem.SystemType)");
+            CodeTypeReferenceExpression(mem.SystemType) // TODO - does it always work?
+          | _ => 
+            {
+              def classType = CodeTypeReferenceExpression(from.SystemType);
+              match(mem)
+              {
+                | mem is IMethod => 
+                  CodeMethodReferenceExpression(classType,
+                                                 mem.Name,
+                                                 type_parms.MapToArray(t => CodeTypeReference(t.SystemType)))
+                | mem is IField => 
+                  CodeFieldReferenceExpression(classType, mem.Name)
+                | mem is IEvent => 
+                  CodeEventReferenceExpression(classType, mem.Name)
+                | mem is IProperty => 
+                  CodePropertyReferenceExpression(classType, mem.Name)
+                | _ =>
+                  throw CodeDomSerializerException($"TExpr.StaticRef member $mem is of unknown type",
+                                                   CodeLinePragma(mem.Location.File,mem.Location.Line));
+              }
+            }
+        }
+
+      | TExpr.LocalRef(decl) =>              //{ decl : LocalValue; }
+        // TODO: is it always correct?
+        if(decl.Name == "_N_closurised_this_ptr") CodeThisReferenceExpression ()
+        else CodeVariableReferenceExpression(decl.Name)
+
+      // | TExpr.ImplicitValueTypeCtor
+      | TExpr.FieldMember(obj,fld) =>          // obj : TExpr; fld : IField; }
+        CodeFieldReferenceExpression(CreateExpression(obj), fld.Name)
+
+      | TExpr.MethodRef(obj,meth,type_parms,_) => // obj : TExpr; meth : IMethod; type_parms : list [TyVar]; notvirtual : bool; }
+        CodeMethodReferenceExpression(CreateExpression(obj),
+                                       meth.Name,
+                                       type_parms.MapToArray(t => CodeTypeReference(t.SystemType)))
+
+      | TExpr.Call(func,parms,_) => // mutable func : TExpr; mutable parms : list [Parm]; mutable is_tail : bool; }
+        Debug.Print($"TExpr.Call of $func of type $(func.GetType().ToString()) with params $parms");
+        def parmArray = parms.MapToArray(p => CreateExpression(p.expr));
+        match(func)
+        {
+          | TExpr.StaticRef(from,mem,_) when(mem.Name == ".ctor") =>
+            CodeObjectCreateExpression(from.SystemType, parmArray)
+          | op is TExpr.OpCode when(parmArray.Length == 2) => // name : string; }
+            CreateBinaryOperator(op,parmArray)
+          | _ =>
+            CodeMethodInvokeExpression(CreateExpression(func) :> CodeMethodReferenceExpression, parmArray)
+        }
+
+      | TExpr.Literal(val) =>       // val : Nemerle.Compiler.Literal; }
+        if(val is Literal.Void) CodeSnippetExpression("") else 
+        CodePrimitiveExpression(val.AsObject(_manager.InternalType))
+
+      | TExpr.This =>
+        CodeThisReferenceExpression()
+
+      | TExpr.Base =>                 // base_ctor : IMethod; }
+        CodeBaseReferenceExpression()
+
+      | TExpr.TypeConversion(expr,target_type,_) => // mutable expr : TExpr; target_type : TyVar; kind : ConversionKind; }
+        CodeCastExpression(target_type.SystemType, CreateExpression(expr)) // TODO: what about kind?
+
+      /*
+      | TExpr.Tuple                 // args : list [TExpr]; }
+      */
+
+      | TExpr.Array(args,dimensions) => // args : list [TExpr]; dimensions : list [TExpr]; }
+        {
+          def elemType = (expr.Type.Fix() :> MType.Array).t.SystemType;
+          if (args != [])
+            CodeArrayCreateExpression( elemType,
+                                       args.MapToArray(CreateExpression(_)))
+          else match(dimensions)
+          {
+            | [dim] => CodeArrayCreateExpression(elemType,CreateExpression(dim))
+            | [] =>
+              throw CodeDomSerializerException("Array is 0-dimensional!",
+                                               CodeDomHelper.GetLinePragma(expr));
+            | _ =>
+              throw CodeDomSerializerException("CodeDom doesn't support multidimensional arrays!",
+                                               CodeDomHelper.GetLinePragma(expr));
+          }
+        }
+
+      | TExpr.TypeOf(target_type) => // target_type : TyVar; }
+        CodeTypeOfExpression( target_type.SystemType )
+
+      | TExpr.ArrayIndexer(obj,args) => // obj : TExpr; args : list [TExpr]; }
+        if (obj.Type.Fix() is MType.Array)
+          CodeArrayIndexerExpression(CreateExpression(obj), args.MapToArray( CreateExpression(_)))
+        else
+          CodeIndexerExpression(CreateExpression(obj), args.MapToArray( CreateExpression(_)))
+
+      /*
+      | TExpr.TupleIndexer          // obj : TExpr; pos : int; len : int; } // 0-based
+      | TExpr.OpCode                // name : string; }
+      */
+      | TExpr.MacroEnvelope as expr => // original : Parsetree.PExpr; the_macro : IMacro; expanded : TExpr; }
+        ProcessMacroExpression(expr)
+
+      | _ =>
+        {Debug.Print($"Ignored: expr of type $(expr.GetType()) = $expr,\n--Creating CodeSnippet ");
+         CodeSnippetExpression($"$expr") }
+      }
+    }
+
+    protected virtual ProcessMacroExpression(macroEnvelope : TExpr.MacroEnvelope) : CodeExpression
+    {
+      | (original,the_macro,expanded) => // original : Parsetree.PExpr; the_macro : IMacro; expanded : TExpr; }
+        Debug.Print($"  ProcessMacroExpression ($(the_macro.GetName())) :\n original=$original,\n"
+                    "expanded = $expanded\n");
+        CreateExpression(expanded)
+    }
+
+    protected CreateCatchClause(tryCase: Try_case) : CodeCatchClause
+    {
+      // TODO : is this the right interpretation?
+      | Fault(handler) => //{ handler : TExpr; }
+        CodeCatchClause("ex",CodeTypeReference(typeof(System.Exception)),CreateStatements(handler))
+
+      | Catch(exn, handler) => // { exn : LocalValue; handler : TExpr; }
+        CodeCatchClause(exn.Name,CodeTypeReference(exn.Type.SystemType),CreateStatements(handler))
+
+      | Filter(exn, filter, handler) => // { exn : LocalValue; filter : TExpr; handler : TExpr; }
+        Debug.WriteLine($"Ignored: Try_case.Filter( $exn, $filter, $handler )");
+        CodeCatchClause()
+    }
+
+    protected CreateBinaryOperator(op: TExpr.OpCode, parms: array[CodeExpression]): CodeBinaryOperatorExpression
+    {
+      CodeBinaryOperatorExpression( parms[0],
+        match(op.name)
+        {
+          | "+" => CodeBinaryOperatorType.Add 
+          | "=" => CodeBinaryOperatorType.Assign
+          | "&" => CodeBinaryOperatorType.BitwiseAnd
+          | "|" => CodeBinaryOperatorType.BitwiseOr
+          | "&&" => CodeBinaryOperatorType.BooleanAnd
+          | "||" => CodeBinaryOperatorType.BooleanOr
+          | @"\" => CodeBinaryOperatorType.Divide
+          | ">" => CodeBinaryOperatorType.GreaterThan
+          | ">=" => CodeBinaryOperatorType.GreaterThanOrEqual
+          | "==" => CodeBinaryOperatorType.IdentityEquality
+          | "!=" => CodeBinaryOperatorType.IdentityInequality
+          | "<" => CodeBinaryOperatorType.LessThan
+          | "<=" => CodeBinaryOperatorType.LessThanOrEqual
+          | "%" => CodeBinaryOperatorType.Modulus
+          | "*" => CodeBinaryOperatorType.Multiply
+          | "-" => CodeBinaryOperatorType.Subtract
+          | "===" => CodeBinaryOperatorType.ValueEquality
+          | name =>
+              throw CodeDomSerializerException($"CodeDom cannot create $name operator!",
+                                               CodeDomHelper.GetLinePragma(op));
+        },
+        parms[1]
+      )
+    }
+
+  }
+}



More information about the svn mailing list