private IValue InterpretCastExpression(SyneryParser.CastExpressionContext context)
        {
            IValue     left           = InterpretExpression(context.expression());
            SyneryType conversionType = Controller.Interpret <SyneryParser.PrimitiveTypeContext, SyneryType>(context.primitiveType());

            if (left.Value != null)
            {
                // try to cast the given value.

                try
                {
                    object result;
                    result = Convert.ChangeType(left.Value, conversionType.UnterlyingDotNetType);
                    return(new TypedValue(conversionType, result));
                }
                catch (Exception)
                {
                    throw new SyneryInterpretationException(context, string.Format("Error with cast expression '{0}'. Cannot cast the value '{1}' of type '{2}' to new type '{3}'.",
                                                                                   context.GetText(), left.Value, left.Type.PublicName, conversionType.PublicName));
                }
            }
            else
            {
                // the given value is NULL.
                // create a new TypedValue with the given type and a NULL value

                return(new TypedValue(conversionType, null));
            }
        }
예제 #2
0
        /// <summary>
        /// Creates a field using the given parameters and adds it to the list of fields
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <param name="parentType"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        private IRecordTypeField AddFieldWithParentType(string name, SyneryType type, IRecordType parentType, IValue defaultValue = null)
        {
            IRecordTypeField field = new RecordTypeField(parentType)
            {
                Name         = name,
                Type         = type,
                DefaultValue = defaultValue,
            };

            _Fields.Add(field);

            return(field);
        }
예제 #3
0
 /// <summary>
 /// Gets the symbol name of a primitive type (e.g. "STRING") or complex type (e.g. "Person" for a "#Person" Record Type).
 /// </summary>
 /// <param name="syneryType"></param>
 /// <returns></returns>
 public static string GetSyneryTypeSymbol(SyneryType syneryType)
 {
     if (String.IsNullOrEmpty(syneryType.Name))
     {
         // it seems to be a primitive type .NET CLR type
         return(GetSyneryTypeSymbol(syneryType.UnterlyingDotNetType));
     }
     else
     {
         // it seems to be a complex type (e.g. Record Type)
         return(syneryType.Name);
     }
 }
        private ExpressionValue GetLibraryPluginVariableValueExpression(SyneryParser.LibraryPluginVariableReferenceContext context)
        {
            string libraryPluginIdentifier;
            string variableIdentifier;
            string fullIdentifier = context.ExternalLibraryIdentifier().GetText();

            // split the identifier

            bool success = FunctionHelper.FragmentLibraryPluginIdentifier(fullIdentifier, out libraryPluginIdentifier, out variableIdentifier);

            if (success == false)
            {
                throw new SyneryInterpretationException(context, "Wasn't able to fragment the library plugin variable identifier. It doesn't have the expected format.");
            }

            // validate the identifer

            if (String.IsNullOrEmpty(libraryPluginIdentifier))
            {
                throw new SyneryInterpretationException(context, "The library plugin identifer is empty.");
            }
            if (String.IsNullOrEmpty(variableIdentifier))
            {
                throw new SyneryInterpretationException(context, "The variable identifer is empty.");
            }

            // find the variable declaration
            IStaticExtensionVariableData variableData = Memory.LibraryPluginManager.GetStaticVariableDataByIdentifier(libraryPluginIdentifier, variableIdentifier);

            // create an expression that calls a method on LibraryPluginManager that looks like these:
            // Memory.LibraryPluginManager.GetStaticVariableWithPrimitiveReturn(variableData)

            MethodInfo executeFunctionMethod = typeof(ILibraryPluginManager)
                                               .GetMethod("GetStaticVariableWithPrimitiveReturn", new Type[] { typeof(IStaticExtensionVariableData) });

            Expression libraryPluginManagerExpression = Expression.Constant(Memory.LibraryPluginManager);

            Expression paramFunctionDataExpression = Expression.Constant(variableData, typeof(IStaticExtensionVariableData));

            Expression methodCallExpression = Expression.Call(
                libraryPluginManagerExpression,
                executeFunctionMethod,
                paramFunctionDataExpression);

            SyneryType resultType = TypeHelper.GetSyneryType(variableData.Type);

            return(new ExpressionValue(
                       expression: methodCallExpression,
                       resultType: resultType));
        }
        private void InterpretDeclaration(SyneryParser.VariableDeclartionContext context)
        {
            SyneryType type = Controller.Interpret <SyneryParser.TypeContext, SyneryType>(context.type());

            foreach (var assignment in context.variableAssignment())
            {
                if (assignment.variableReference() != null)
                {
                    string name = assignment.variableReference().GetText();

                    // create new variable in scope
                    Memory.CurrentScope.DeclareVariable(name, type);

                    InterpretAssignment(assignment);
                }
            }
        }
        /// <summary>
        /// Creates an Expression that casts a value into an other type.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="queryMemory"></param>
        /// <returns></returns>
        private IExpressionValue InterpretCastExpression(SyneryParser.RequestCastExpressionContext context, QueryMemory queryMemory)
        {
            IExpressionValue left                 = InterpretRequestExpression(context.requestExpression(), queryMemory);
            SyneryType       targetSyneryType     = Controller.Interpret <SyneryParser.PrimitiveTypeContext, SyneryType>(context.primitiveType());
            Type             targetConversionType = targetSyneryType.UnterlyingDotNetType;

            // create an Expression that calls the Convert.ChangeType(value, type); method
            MethodInfo convetToString       = typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(Type) });
            Expression changeTypeExpression = Expression.Call(convetToString, Expression.Convert(left.Expression, typeof(object)), Expression.Constant(targetConversionType));

            Expression fieldExpression = Expression.Convert(changeTypeExpression, targetConversionType);

            return(new ExpressionValue(
                       resultType: targetSyneryType,
                       expression: fieldExpression
                       ));
        }
예제 #7
0
 /// <summary>
 /// Checks whether the given SyneryType is a primitive .NET CLR type.
 /// An opposite of a primitive type for example would be a Record Type.
 /// </summary>
 /// <param name="syneryType"></param>
 /// <returns></returns>
 public static bool IsPrimitiveType(SyneryType syneryType)
 {
     return(SUPPORTED_DOTNET_TYPES.Contains(syneryType.UnterlyingDotNetType));
 }
예제 #8
0
 public ExpressionValue(Expression expression, SyneryType resultType)
 {
     Expression = expression;
     ResultType = resultType;
 }
예제 #9
0
        /// <summary>
        /// Tries to find the function declaration with the matching function signature. It also considers that a parameter
        /// isn't set because a default value is available
        ///
        /// EXAMPLE:
        ///
        /// myFunc(string first, string second = "default")
        ///     // do something...
        /// END
        ///
        /// // call with one parameter
        /// myFunc("first parameter");
        /// </summary>
        /// <param name="memory">the SyneryMemory that contains a list with all available functions.</param>
        /// <param name="identifier">the name of the function</param>
        /// <param name="listOfParameterTypes">the types of all available parameters</param>
        /// <returns></returns>
        public static IFunctionData FindSyneryFunctionDeclaration(ISyneryMemory memory, string identifier, SyneryType[] listOfParameterTypes)
        {
            // try to find function(s) with the same name with at least the same number of parameters as given
            IEnumerable <IFunctionData> listOfFunctionData =
                from f in memory.Functions
                where f.FullName == IdentifierHelper.GetIdentifierBasedOnFunctionScope(memory, identifier) &&
                f.FunctionDefinition.Parameters.Count >= listOfParameterTypes.Count()
                select f;

            // try to find the matching function signature
            // also consider that a parameter isn't set because a default value is available
            foreach (IFunctionData data in listOfFunctionData)
            {
                bool isMatching = true;

                for (int i = 0; i < data.FunctionDefinition.Parameters.Count; i++)
                {
                    if (listOfParameterTypes.Count() > i && listOfParameterTypes[i] != null)
                    {
                        SyneryType expectedType = data.FunctionDefinition.Parameters[i].Type;
                        SyneryType givenType    = listOfParameterTypes[i];

                        // compare the types of the expected parameter and the given value
                        if (givenType != expectedType)
                        {
                            // maybe these are two record-types which derive from each other
                            if (givenType.UnterlyingDotNetType != typeof(IRecord) ||
                                expectedType.UnterlyingDotNetType != typeof(IRecord))
                            {
                                isMatching = false;
                            }
                            else
                            {
                                string expectedTypeName = IdentifierHelper.GetFullName(expectedType.Name, data.CodeFileAlias);

                                if (!RecordHelper.IsDerivedType(memory, givenType.Name, expectedTypeName))
                                {
                                    isMatching = false;
                                }
                            }
                        }
                    }
                    else
                    {
                        // no value given for the parameter: check whether there is a default value
                        if (data.FunctionDefinition.Parameters[i].DefaultValue == null)
                        {
                            isMatching = false;
                        }
                    }
                }

                // the current function declaration seems to match -> return it
                if (isMatching == true)
                {
                    return(data);
                }
            }

            // no matching function declaration found
            return(null);
        }
예제 #10
0
 public TypedValue(SyneryType syneryType, object value = null)
 {
     Value = value;
     Type  = syneryType;
 }
예제 #11
0
 /// <summary>
 /// Creates a new field declaration and adds it to the record type.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="type"></param>
 /// <param name="defaultValue"></param>
 /// <returns></returns>
 public IRecordTypeField AddField(string name, SyneryType type, IValue defaultValue = null)
 {
     return(AddFieldWithParentType(name, type, this, defaultValue));
 }
예제 #12
0
        /// <summary>
        /// Executes the function from the given <paramref name="functionData"/> using the given <paramref name="controller"/> and by setting the <paramref name="listOfParameters"/> as local scope variables.
        /// </summary>
        /// <param name="controller">the controller that is used to interpret the function</param>
        /// <param name="functionData">contains the data for the function that should be executed</param>
        /// <param name="listOfParameters"></param>
        /// <param name="functionCallContext">the synery context where the function is called (only used in exceptions)</param>
        /// <returns>the return value may be null if the function definition says HasReturnValue=false</returns>
        public static IValue ExecuteSyneryFunction(IInterpretationController controller, IFunctionData functionData, object[] listOfParameters, Antlr4.Runtime.ParserRuleContext functionCallContext)
        {
            IValue returnValue;
            IDictionary <string, IValue> scopeVariables = new Dictionary <string, IValue>();
            int sizeOfSignatureParameters = functionData.FunctionDefinition.Parameters.Count;
            int sizeOfListOfParameters    = listOfParameters.Count();

            // prepare the parameters as local scope variables

            for (int i = 0; i < sizeOfSignatureParameters; i++)
            {
                object     variableValue = null;
                string     variableName  = functionData.FunctionDefinition.Parameters[i].Name;
                SyneryType variableType  = functionData.FunctionDefinition.Parameters[i].Type;

                if (sizeOfListOfParameters >= (i + 1) &&
                    listOfParameters[i] != null)
                {
                    variableValue = listOfParameters[i];
                }
                else if (functionData.FunctionDefinition.Parameters[i].DefaultValue != null)
                {
                    variableValue = functionData.FunctionDefinition.Parameters[i].DefaultValue.Value;
                }

                scopeVariables.Add(variableName, new TypedValue(variableType, variableValue));
            }

            // start executing the function context

            if (functionData.Context is SyneryParser.BlockContext)
            {
                /* 1. Create scope for the function block with the given parameters set as variables.
                 *    Set the global scope as parent to avoid accessing variables of this scope.
                 * 2. Execute the function block.
                 * 3. Get the return value from the function block.
                 */

                IFunctionScope functionScope = new FunctionScope(controller.Memory.GlobalScope, functionData, scopeVariables);

                controller.Interpret <SyneryParser.BlockContext, INestedScope, INestedScope>((SyneryParser.BlockContext)functionData.Context, functionScope);

                returnValue = functionScope.ReturnValue;
            }
            else
            {
                throw new SyneryInterpretationException(functionData.Context, "Unknown function content cannot be interpreted.");
            }

            // validate the return value

            if (functionData.FunctionDefinition.HasReturnValue == true && returnValue == null)
            {
                string message = String.Format(
                    "Function has no return value but is expected to return '{0}'. Function called on line: '{1}'.",
                    functionData.FunctionDefinition.ReturnType.PublicName,
                    functionCallContext.Start.Line);

                throw new SyneryInterpretationException(functionData.Context, message);
            }
            else if (functionData.FunctionDefinition.HasReturnValue == true &&
                     functionData.FunctionDefinition.ReturnType != returnValue.Type)
            {
                string message = String.Format(
                    "Function has wrong return value. Expected: '{0}' / Given: '{1}'. Function called on line: '{2}'.",
                    functionData.FunctionDefinition.ReturnType.PublicName,
                    returnValue.Type.PublicName,
                    functionCallContext.Start.Line);
                throw new SyneryInterpretationException(functionData.Context, message);
            }

            return(returnValue);
        }
예제 #13
0
 /// <summary>
 /// Creates a new space in memory for a variable with the given name and type.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="type"></param>
 public void DeclareVariable(string name, SyneryType type)
 {
     _Variables[name] = new TypedValue(type);
 }
예제 #14
0
        public IValue RunWithResult(SyneryParser.LiteralContext context)
        {
            SyneryType type         = null;
            object     literalValue = null;

            if (context.StringLiteral() != null)
            {
                type         = TypeHelper.STRING_TYPE;
                literalValue = LiteralHelper.ParseStringLiteral(context.StringLiteral());
            }
            else if (context.VerbatimStringLiteral() != null)
            {
                type         = TypeHelper.STRING_TYPE;
                literalValue = LiteralHelper.ParseVerbatimStringLiteral(context.VerbatimStringLiteral());
            }
            else if (context.IntegerLiteral() != null)
            {
                type         = TypeHelper.INT_TYPE;
                literalValue = Convert.ChangeType(context.GetText(), typeof(int));
            }
            else if (context.DoubleLiteral() != null)
            {
                type         = TypeHelper.DOUBLE_TYPE;
                literalValue = Convert.ToDouble(context.GetText(), new NumberFormatInfo()
                {
                    NumberDecimalSeparator = "."
                });
            }
            else if (context.DecimalLiteral() != null)
            {
                type = TypeHelper.DECIMAL_TYPE;
                string decimalValue = context.GetText().TrimEnd(new char[] { 'M', 'm' });

                literalValue = Convert.ToDecimal(decimalValue, new NumberFormatInfo()
                {
                    NumberDecimalSeparator = "."
                });
            }
            else if (context.CharLiteral() != null)
            {
                type = TypeHelper.CHAR_TYPE;
                char[] chars = context.GetText().ToCharArray(1, 1);

                if (chars.Length == 1)
                {
                    literalValue = Convert.ToChar(chars[0]);
                }
                else
                {
                    throw new SyneryInterpretationException(context, String.Format("The value '{0}' is not a valid char literal.", context.GetText()));
                }
            }
            else if (context.BooleanLiteral() != null)
            {
                type = TypeHelper.BOOL_TYPE;
                if (context.BooleanLiteral().GetText() == "TRUE")
                {
                    literalValue = true;
                }
                else if (context.BooleanLiteral().GetText() == "FALSE")
                {
                    literalValue = false;
                }
                else
                {
                    throw new SyneryInterpretationException(context, String.Format("The value '{0}' is not a valid boolean literal.", context.GetText()));
                }
            }
            else if (context.dateTimeLiteral() != null)
            {
                type         = TypeHelper.DATETIME_TYPE;
                literalValue = Controller.Interpret <SyneryParser.DateTimeLiteralContext, DateTime>(context.dateTimeLiteral());
            }
            else if (context.NullLiteral() != null)
            {
                type         = null;
                literalValue = null;
            }
            else
            {
                throw new SyneryInterpretationException(context,
                                                        String.Format("Unknown Literal type in {0} for the value '{0}'.", this.GetType().Name, context.GetText()));
            }

            return(new TypedValue(type, literalValue));
        }
        private void ExtractRecordTypes(string code, IDictionary <string, string> includeCode = null)
        {
            int endlessLoopPreventionCounter = 0;
            IList <RecordTypeDelcarationContainer> listOfDeclrartionContainer = GetRecordTypeContexts(code, includeCode);

            // assure that there is a dictionary
            if (Memory.RecordTypes == null)
            {
                Memory.RecordTypes = new Dictionary <SyneryType, IRecordType>();
            }

            // extract all RecordTypes without a base type

            var listOfDeclarationsWithoutBaseType = (from d in listOfDeclrartionContainer
                                                     where d.BaseRecordFullName == null
                                                     select d).ToList();

            foreach (var item in listOfDeclarationsWithoutBaseType)
            {
                IRecordType recordType = Controller
                                         .Interpret <SyneryParser.RecordTypeDeclarationContext, IRecordType, RecordTypeDelcarationContainer>(item.RecordTypeDeclarationContext, item);

                SyneryType syneryType = new SyneryType(typeof(IRecord), recordType.FullName);

                // set the alias of the included code file
                if (item.CodeFileAlias != null)
                {
                    recordType.CodeFileAlias = item.CodeFileAlias;
                }

                Memory.RecordTypes.Add(syneryType, recordType);
                listOfDeclrartionContainer.Remove(item);
            }

            // loop threw the list of RecordTypes with a base type
            // assure that a RecordType only is loaded if the base type already is available

            while (listOfDeclrartionContainer.Count != 0)
            {
                var listOfAvailableTypes = Memory.RecordTypes.Select(r => r.Value.FullName);
                var listOfDeclarationsWithAvailableBaseTypes = (from d in listOfDeclrartionContainer
                                                                where listOfAvailableTypes.Contains(d.BaseRecordFullName)
                                                                select d).ToList();

                // extract all RecordTypes for which the base type already is available

                foreach (var item in listOfDeclarationsWithAvailableBaseTypes)
                {
                    IRecordType recordType = Controller
                                             .Interpret <SyneryParser.RecordTypeDeclarationContext, IRecordType, RecordTypeDelcarationContainer>(item.RecordTypeDeclarationContext, item);

                    SyneryType syneryType = new SyneryType(typeof(IRecord), recordType.FullName);

                    // set the alias of the included code file
                    if (item.CodeFileAlias != null)
                    {
                        recordType.CodeFileAlias = item.CodeFileAlias;
                    }

                    Memory.RecordTypes.Add(syneryType, recordType);
                    listOfDeclrartionContainer.Remove(item);
                }

                // prevent an endless loop:
                // if the counter reaches the 1000-mark the loop is stopped by throwing an exception

                endlessLoopPreventionCounter++;

                if (endlessLoopPreventionCounter > 1000)
                {
                    // throw an exception that contains the name(s) of the left declarations that couldn't be resolved

                    throw new SyneryException(String.Format(
                                                  "The base type for the following record types couldn't be resolved: {0}",
                                                  String.Join(", ", listOfDeclrartionContainer.Select(d => String.Format("'{0} : {1}'", d.FullName, d.BaseRecordFullName)))));
                }
            }
        }
        private static KeyValuePair <SyneryType, IRecordType> GetRecordTypeSignature(IRecordType recordType)
        {
            SyneryType syneryType = new SyneryType(typeof(IRecord), recordType.Name);

            return(new KeyValuePair <SyneryType, IRecordType>(syneryType, recordType));
        }
 public static IValue GetDefaultValue(SyneryType type)
 {
     return(GetDefaultValue(type.UnterlyingDotNetType));
 }