Click here to Skip to main content
Click here to Skip to main content
Articles » Languages » C# » General » Downloads
 
Add your own
alternative version
Go to top

Conscript: An embeddable, compiled scripting language for .NET

, 5 Sep 2008
An API for enhancing any .NET application with a scripting language
conscript_api_and_demo_source.zip
Conscript_API_&_Demo_Source
Conscript
ConscriptDemo
Conscript.ico
Properties
Settings.settings
vssver2.scc
Resources
Conscript.ico
vssver2.scc
vssver2.scc
Collections
vssver2.scc
Compiler
vssver2.scc
Conscript.doxyfile
Properties
vssver2.scc
Resources
Conscript.ico
vssver2.scc
Runtime
vssver2.scc
vssver2.scc
SampleScripts
BubbleSort.cns
Dungeon.cns
Factorial.cns
HelloWorld.cns
vssver2.scc
using System;
using System.Collections.Generic;
using System.Text;

using Conscript.Runtime;

namespace Conscript.Compiler
{
    internal class TypeInferer
    {
        #region Private Static Variables

        private static Dictionary<TokenType, Dictionary<String, Type>> s_dictInferenceMap;

        #endregion

        #region Private Methods

        private String MakeKey(Type typeDest, Type typeSource)
        {
            return typeDest + "-" + typeSource;
        }

        private String GetTypeDescription(Type type)
        {
            if (type == null) return "Unknown";

            if (type == typeof(NullReference))
                return "Null";
            else if (type == typeof(int))
                return "Integer";
            else if (type == typeof(float))
                return "Float";
            else if (type == typeof(bool))
                return "Boolean";
            else if (type == typeof(String))
                return "String";
            else if (type == typeof(AssociativeArray))
                return "Array";
            else
                throw new ParserException("Type '" + type.Name
                    + "' not supported by type inference system.");
        }

        #endregion;

        #region Public Methods

        public TypeInferer()
        {
            if (s_dictInferenceMap != null) return;

            s_dictInferenceMap = new Dictionary<TokenType, Dictionary<String, Type>>();

            Type typeNull = typeof(NullReference);
            Type typeInt = typeof(int);
            Type typeFloat = typeof(float);
            Type typeBool = typeof(bool);
            Type typeString = typeof(String);
            Type typeArray = typeof(AssociativeArray);

            // And, Or
            Dictionary<String, Type> dictInferenceAndOr = new Dictionary<string, Type>();

            dictInferenceAndOr[MakeKey(null, null)] = typeBool;
            dictInferenceAndOr[MakeKey(null, typeBool)] = typeBool;
            dictInferenceAndOr[MakeKey(typeBool, null)] = typeBool;
            dictInferenceAndOr[MakeKey(typeBool, typeBool)] = typeBool;

            s_dictInferenceMap[TokenType.And] = dictInferenceAndOr;
            s_dictInferenceMap[TokenType.Or] = dictInferenceAndOr;

            // equal, not equal
            Dictionary<String, Type> dictInferenceEquality = new Dictionary<string, Type>();

            dictInferenceEquality[MakeKey(null, null)] = typeBool;
            dictInferenceEquality[MakeKey(null, typeNull)] = typeBool;
            dictInferenceEquality[MakeKey(null, typeInt)] = typeBool;
            dictInferenceEquality[MakeKey(null, typeFloat)] = typeBool;
            dictInferenceEquality[MakeKey(null, typeBool)] = typeBool;
            dictInferenceEquality[MakeKey(null, typeString)] = typeBool;

            dictInferenceEquality[MakeKey(typeNull, null)] = typeBool;
            dictInferenceEquality[MakeKey(typeNull, typeNull)] = typeBool;

            dictInferenceEquality[MakeKey(typeInt, null)] = typeBool;
            dictInferenceEquality[MakeKey(typeInt, typeInt)] = typeBool;
            dictInferenceEquality[MakeKey(typeInt, typeFloat)] = typeBool;

            dictInferenceEquality[MakeKey(typeFloat, null)] = typeBool;
            dictInferenceEquality[MakeKey(typeFloat, typeInt)] = typeBool;
            dictInferenceEquality[MakeKey(typeFloat, typeFloat)] = typeBool;

            dictInferenceEquality[MakeKey(typeBool, null)] = typeBool;
            dictInferenceEquality[MakeKey(typeBool, typeBool)] = typeBool;

            dictInferenceEquality[MakeKey(typeString, null)] = typeBool;
            dictInferenceEquality[MakeKey(typeString, typeString)] = typeBool;

            s_dictInferenceMap[TokenType.Equal] = dictInferenceEquality;
            s_dictInferenceMap[TokenType.NotEqual] = dictInferenceEquality;

            // >, >=, <, <=
            Dictionary<String, Type> dictInferenceRelative = new Dictionary<string, Type>();

            dictInferenceRelative[MakeKey(null, null)] = typeBool;
            dictInferenceRelative[MakeKey(null, typeInt)] = typeBool;
            dictInferenceRelative[MakeKey(null, typeFloat)] = typeBool;
            dictInferenceRelative[MakeKey(null, typeString)] = typeBool;

            dictInferenceRelative[MakeKey(typeInt, null)] = typeBool;
            dictInferenceRelative[MakeKey(typeInt, typeInt)] = typeBool;
            dictInferenceRelative[MakeKey(typeInt, typeFloat)] = typeBool;

            dictInferenceRelative[MakeKey(typeFloat, null)] = typeBool;
            dictInferenceRelative[MakeKey(typeFloat, typeInt)] = typeBool;
            dictInferenceRelative[MakeKey(typeFloat, typeFloat)] = typeBool;

            dictInferenceRelative[MakeKey(typeString, null)] = typeBool;
            dictInferenceRelative[MakeKey(typeString, typeString)] = typeBool;

            s_dictInferenceMap[TokenType.Greater] = dictInferenceRelative;
            s_dictInferenceMap[TokenType.GreaterOrEqual] = dictInferenceRelative;
            s_dictInferenceMap[TokenType.Less] = dictInferenceRelative;
            s_dictInferenceMap[TokenType.LessOrEqual] = dictInferenceRelative;

            // plus
            Dictionary<String, Type> dictInferencePlus = new Dictionary<string, Type>();
            dictInferencePlus[MakeKey(null, null)] = null;
            dictInferencePlus[MakeKey(null, typeInt)] = null;
            dictInferencePlus[MakeKey(null, typeFloat)] = null;
            dictInferencePlus[MakeKey(null, typeBool)] = null;
            dictInferencePlus[MakeKey(null, typeString)] = null;
            dictInferencePlus[MakeKey(null, typeArray)] = typeArray;

            dictInferencePlus[MakeKey(typeInt, null)] = null;
            dictInferencePlus[MakeKey(typeInt, typeInt)] = typeInt;
            dictInferencePlus[MakeKey(typeInt, typeFloat)] = typeFloat;

            dictInferencePlus[MakeKey(typeFloat, null)] = null;
            dictInferencePlus[MakeKey(typeFloat, typeInt)] = typeFloat;
            dictInferencePlus[MakeKey(typeFloat, typeFloat)] = typeFloat;

            dictInferencePlus[MakeKey(typeString, null)] = typeString;
            dictInferencePlus[MakeKey(typeString, typeInt)] = typeString;
            dictInferencePlus[MakeKey(typeString, typeFloat)] = typeString;
            dictInferencePlus[MakeKey(typeString, typeBool)] = typeString;
            dictInferencePlus[MakeKey(typeString, typeString)] = typeString;
            dictInferencePlus[MakeKey(typeString, typeArray)] = typeString;

            dictInferencePlus[MakeKey(typeArray, null)] = typeArray;
            dictInferencePlus[MakeKey(typeArray, typeInt)] = typeArray;
            dictInferencePlus[MakeKey(typeArray, typeFloat)] = typeArray;
            dictInferencePlus[MakeKey(typeArray, typeBool)] = typeArray;
            dictInferencePlus[MakeKey(typeArray, typeString)] = typeArray;
            dictInferencePlus[MakeKey(typeArray, typeArray)] = typeArray;

            s_dictInferenceMap[TokenType.Plus] = dictInferencePlus;

            // minus
            Dictionary<String, Type> dictInferenceMinus = new Dictionary<string, Type>();
            dictInferenceMinus[MakeKey(null, null)] = null;
            dictInferenceMinus[MakeKey(null, typeInt)] = null;
            dictInferenceMinus[MakeKey(null, typeFloat)] = null;
            dictInferenceMinus[MakeKey(null, typeBool)] = typeArray;
            dictInferenceMinus[MakeKey(null, typeString)] = null;
            dictInferenceMinus[MakeKey(null, typeArray)] = typeArray;

            dictInferenceMinus[MakeKey(typeInt, null)] = null;
            dictInferenceMinus[MakeKey(typeInt, typeInt)] = typeInt;
            dictInferenceMinus[MakeKey(typeInt, typeFloat)] = typeFloat;

            dictInferenceMinus[MakeKey(typeFloat, null)] = null;
            dictInferenceMinus[MakeKey(typeFloat, typeInt)] = typeFloat;
            dictInferenceMinus[MakeKey(typeFloat, typeFloat)] = typeFloat;

            dictInferenceMinus[MakeKey(typeString, null)] = typeString;
            dictInferenceMinus[MakeKey(typeString, typeString)] = typeString;

            dictInferenceMinus[MakeKey(typeArray, null)] = typeArray;
            dictInferenceMinus[MakeKey(typeArray, typeInt)] = typeArray;
            dictInferenceMinus[MakeKey(typeArray, typeFloat)] = typeArray;
            dictInferenceMinus[MakeKey(typeArray, typeBool)] = typeArray;
            dictInferenceMinus[MakeKey(typeArray, typeString)] = typeArray;
            dictInferenceMinus[MakeKey(typeArray, typeArray)] = typeArray;

            s_dictInferenceMap[TokenType.Minus] = dictInferenceMinus;

            // multiply, divide, power, modulo
            Dictionary<String, Type> dictInferenceFactor = new Dictionary<string, Type>();

            dictInferenceFactor[MakeKey(null, null)] = null;
            dictInferenceFactor[MakeKey(null, typeInt)] = null;
            dictInferenceFactor[MakeKey(null, typeFloat)] = typeFloat;

            dictInferenceFactor[MakeKey(typeInt, null)] = null;
            dictInferenceFactor[MakeKey(typeInt, typeInt)] = typeInt;
            dictInferenceFactor[MakeKey(typeInt, typeFloat)] = typeFloat;

            dictInferenceFactor[MakeKey(typeFloat, null)] = typeFloat;
            dictInferenceFactor[MakeKey(typeFloat, typeInt)] = typeFloat;
            dictInferenceFactor[MakeKey(typeFloat, typeFloat)] = typeFloat;

            s_dictInferenceMap[TokenType.Multiply] = dictInferenceFactor;
            s_dictInferenceMap[TokenType.Divide] = dictInferenceFactor;
            s_dictInferenceMap[TokenType.Power] = dictInferenceFactor;
            s_dictInferenceMap[TokenType.Modulo] = dictInferenceFactor;
        }

        public Type GetInferredType(Token token, Type typeDest, Type typeSource)
        {
            if (!s_dictInferenceMap.ContainsKey(token.Type))
                throw new ParserException(
                    "Cannot infer type for token '" + token
                    + "' as it is not a binary operator.");

            Dictionary<String, Type> dictInferenceSubMap
                = s_dictInferenceMap[token.Type];

            String strKey = MakeKey(typeDest, typeSource);
            if (!dictInferenceSubMap.ContainsKey(strKey))
            {
                String strTypeDest = GetTypeDescription(typeDest);
                String strTypeSource = GetTypeDescription(typeSource);
                throw new ParserException(
                    "Binary operation '" + token.Lexeme
                    + "' cannot be applied on types " + strTypeDest
                    + " and " + strTypeSource + ".");
            }

            return dictInferenceSubMap[strKey];
        }

        #endregion
    }
}

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 Code Project Open License (CPOL)

Share

About the Author

Colin Vella
Software Developer (Senior)
Malta Malta
No Biography provided

| Advertise | Privacy | Mobile
Web01 | 2.8.140916.1 | Last Updated 5 Sep 2008
Article Copyright 2007 by Colin Vella
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid