Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Implementing Programming Languages Using C# 4.0

, 12 Jul 2012
An introduction to creating programming language tools using C# 4.0.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Diggins.Jigsaw
{
    public static class Primitives
    {
        public static void noop() { }
        public static dynamic add(dynamic a, dynamic b) { return a + b; }
        public static dynamic subtract(dynamic a, dynamic b) { return a - b; }
        public static dynamic multiply(dynamic a, dynamic b) { return a * b; }
        public static dynamic divide(dynamic a, dynamic b) { return a / b; }
        public static dynamic modulo(dynamic a, dynamic b) { return a % b; }
        public static dynamic negative(dynamic a) { return -a; }
        public static dynamic shift_left(dynamic a, dynamic b) { return a << b; }
        public static dynamic shift_right(dynamic a, dynamic b) { return a >> b; }
        public static dynamic gt(dynamic a, dynamic b) { return a > b; }
        public static dynamic lt(dynamic a, dynamic b) { return a < b; }
        public static dynamic gteq(dynamic a, dynamic b) { return a >= b; }
        public static dynamic lteq(dynamic a, dynamic b) { return a <= b; }
        public static dynamic eq(dynamic a, dynamic b) { return a.Equals(b); }
        public static dynamic hash(dynamic a) { return a.GetHashCode(); }
        public static dynamic neq(dynamic a, dynamic b) { return a != b; }
        public static dynamic cond(dynamic a, dynamic b, dynamic c) { return a ? b : c; }    
        public static dynamic not(dynamic a) { return !a; }
        public static dynamic or(dynamic a, dynamic b) { return a || b; }
        public static dynamic and(dynamic a, dynamic b) { return a && b; }
        public static dynamic xor(dynamic a, dynamic b) { return a ^ b; }
        public static dynamic bit_or(dynamic a, dynamic b) { return a | b; }
        public static dynamic bit_and(dynamic a, dynamic b) { return a & b; }
        public static dynamic complement(dynamic a) { return ~a; }
        public static dynamic invoke(dynamic f, dynamic args) { return f(args); }
        public static void invoke_void(dynamic f, dynamic args) { f(args); }
        public static dynamic @true() { return true; }
        public static dynamic @false() { return false; }
        public static dynamic succ(dynamic a) { return a + 1; }
        public static dynamic pred(dynamic a) { return a - 1; }
        public static dynamic head(dynamic a) { return a.Head; }
        public static dynamic tail(dynamic a) { return a.Tail; }
        public static dynamic nil() { return List.Empty; }
        public static dynamic pair(dynamic a, dynamic b) { return List.Cons(a, b); }
        public static dynamic type(dynamic a) { return a.GetType(); }
        public static void print(dynamic a) { Console.Write(a); }
        public static dynamic tostring(dynamic a) { return a.ToString(); }
        public static dynamic index(dynamic obj, dynamic index) { return obj[index]; }
        public static dynamic dynamic_invoke(dynamic func, dynamic[] args) { return func.DynamicInvoke(args); }
        
        public static MethodInfo GetMethod(string s)
        {
            return typeof(Primitives).GetMethod(s);
        }

        public static string UnaryOperatorToMethodName(string s)
        {
            switch(s)
            {
                case "-": return "negative";
                case "!": return "not";
                case "~": return "complement";
                default: throw new Exception("Not a recognized unary operator " + s);
            }
        }

        public static string GetMethodNameFromBinaryOperator(string s)
        {
            switch (s)
            {
                case "+": return "add";
                case "-": return "subtract";
                case "*": return "multiply";
                case "/": return "divide";
                case "%": return "modulo";
                case ">>": return "shl";
                case "<<": return "shr";
                case ">": return "gt";
                case "<": return "lt";
                case ">=": return "gteq";
                case "<=": return "lteq";
                case "==": return "eq";
                case "!=": return "neq";
                case "||": return "or";
                case "&&": return "and";
                case "^": return "xor";
                case "|": return "bit_or";
                case "&": return "bit_nand";
                default: throw new Exception("Not a recognized operator");
            }
        }

        public static dynamic Eval(string op, dynamic a0, dynamic a1)
        {
            return GetMethodFromBinaryOperator(op).Invoke(null, new[] { a0, a1 });
        }

        public static MethodInfo GetMethodFromBinaryOperator(string s)
        {
            return GetMethod(GetMethodNameFromBinaryOperator(s));
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License

Share

About the Author

Christopher Diggins
Software Developer Autodesk
Canada Canada
This article was written by Christopher Diggins, a computer science nerd who currently works at Autodesk as an SDK specialist.
Follow on   Twitter   Google+   LinkedIn

| Advertise | Privacy | Mobile
Web03 | 2.8.140821.2 | Last Updated 12 Jul 2012
Article Copyright 2011 by Christopher Diggins
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid