public override IMethodValue VisitFunctionAssignment_Ex([NotNull] ClepsParser.FunctionAssignmentContext context)
        {
            var             oldCurrMethodRegister = CurrMethodGenerator;
            VariableManager variableManager       = new VariableManager();

            VariableManagers.Add(variableManager);

            ClepsType returnType = VoidClepsType.GetVoidType();

            if (context.FunctionReturnType != null)
            {
                returnType = Visit(context.FunctionReturnType) as ClepsType;
            }

            List <ClepsVariable> functionParameters = context._FunctionParameters.Select(p => Visit(p) as ClepsVariable).ToList();

            FunctionClepsType functionType = new FunctionClepsType(functionParameters.Select(p => p.VariableType).ToList(), returnType);

            var newMethod = CodeGenerator.CreateNewMethod(functionType);

            CurrMethodGenerator = newMethod;

            CurrMethodGenerator.SetFormalParameterNames(functionParameters.Select(p => p.VariableName).ToList());

            functionParameters.ForEach(variable => {
                variableManager.AddLocalVariable(variable, CurrMethodGenerator.GetFormalParameterRegister(variable.VariableName));
            });

            Visit(context.statementBlock());

            VariableManagers.RemoveAt(VariableManagers.Count - 1);
            CurrMethodGenerator = oldCurrMethodRegister;
            return(newMethod);
        }
Пример #2
0
        public sealed override object VisitTypenameAndVoid([NotNull] ClepsParser.TypenameAndVoidContext context)
        {
            if (context.typename() != null)
            {
                return(Visit(context.typename()));
            }

            var ret = VoidClepsType.GetVoidType();

            return(ret);
        }
Пример #3
0
        public sealed override object VisitFunctionAssignment([NotNull] ClepsParser.FunctionAssignmentContext context)
        {
            var oldCurrentBlockStatus = CurrentBlockStatus;

            CurrentBlockStatus = new List <StatementBlockStatus>()
            {
                new StatementBlockStatus(StatementBlockSource.Function)
            };

            IMethodValue functionType = VisitFunctionAssignment_Ex(context);

            if ((functionType.ExpressionType as FunctionClepsType).ReturnType != VoidClepsType.GetVoidType() && !CurrentBlockStatus.Last().ReturnStatementReached)
            {
                string errorMessage = "Not all pathways have return statements";
                Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
            }

            CurrentBlockStatus = oldCurrentBlockStatus;

            return(functionType);
        }
        private IValue doFunctionCall(ParserRuleContext context, string targetFunctionName, List <IValue> parameters, IValue target, ClepsType targetType, bool allowVoidReturn)
        {
            IValue         dereferencedTarget = target == null? null : GetDereferencedRegisterOrNull(target);
            BasicClepsType dereferencedType   = target == null? targetType as BasicClepsType : dereferencedTarget.ExpressionType as BasicClepsType;

            if (dereferencedType == null)
            {
                string errorMessage = String.Format("Could not dereference expression on type {0}", targetType.GetClepsTypeString());
                Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                //just return something to avoid stalling
                return(CodeGenerator.CreateByte(0));
            }

            ClepsClass targetClepsClass = ClassManager.GetClass(dereferencedType.GetClepsTypeString());


            List <ClepsVariable> functionOverloads;
            bool isStatic;

            if (targetClepsClass.StaticMemberMethods.ContainsKey(targetFunctionName))
            {
                isStatic          = true;
                functionOverloads = targetClepsClass.StaticMemberMethods[targetFunctionName];
            }
            else if (target != null && targetClepsClass.MemberMethods.ContainsKey(targetFunctionName))
            {
                isStatic          = false;
                functionOverloads = targetClepsClass.MemberMethods[targetFunctionName];
            }
            else
            {
                string errorMessage = String.Format("Class {0} does not contain a {1}static function called {2}.", targetClepsClass.FullyQualifiedName, target == null? "" : "member or ", targetFunctionName);
                Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                //Just return something to avoid stalling compilation
                return(CodeGenerator.CreateByte(0));
            }

            int    matchedPosition;
            string fnMatchErrorMessage;

            if (!FunctionOverloadManager.FindMatchingFunctionType(TypeManager, functionOverloads, parameters, out matchedPosition, out fnMatchErrorMessage))
            {
                Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, fnMatchErrorMessage));
                //Just return something to avoid stalling compilation
                return(CodeGenerator.CreateByte(0));
            }

            FunctionClepsType chosenFunctionType = functionOverloads[matchedPosition].VariableType as FunctionClepsType;

            if (!allowVoidReturn && chosenFunctionType.ReturnType == VoidClepsType.GetVoidType())
            {
                string errorMessage = String.Format("Function {0} does not return a value", targetFunctionName);
                Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                //Just return something to avoid stalling compilation
                return(CodeGenerator.CreateByte(0));
            }

            IValue returnValue = CodeGenerator.GetFunctionCallReturnValue(isStatic? null : dereferencedTarget, dereferencedType, targetFunctionName, chosenFunctionType, parameters);

            return(returnValue);
        }
Пример #5
0
        public void CreateClass(string className)
        {
            ClassesLoaded.Add(className, null);
            ClassInitializers[className]       = new JavaScriptMethod(new FunctionClepsType(new List <ClepsType>(), VoidClepsType.GetVoidType()));
            ClassStaticInitializers[className] = new JavaScriptMethod(new FunctionClepsType(new List <ClepsType>(), VoidClepsType.GetVoidType()));

            //static initializing should occur only once
            ClassStaticInitializers[className].CreateIfStatementBlock(new JavaScriptValue("![" + JavaScriptCodeParameters.TOPLEVELNAMESPACE + "." + className + ".classStaticInitialized]", CompilerConstants.ClepsBoolType));
            ClassStaticInitializers[className].CreateAssignment(new JavaScriptRegister(JavaScriptCodeParameters.TOPLEVELNAMESPACE + "." + className + ".classStaticInitialized", CompilerConstants.ClepsBoolType), new JavaScriptValue("[true]", CompilerConstants.ClepsBoolType));
        }
Пример #6
0
        public void Initiate()
        {
            FunctionClepsType voidFuncType = new FunctionClepsType(new List <ClepsType>(), VoidClepsType.GetVoidType());

            ClassesLoaded            = new Dictionary <string, ClepsClass>();
            ClassInitializers        = new Dictionary <string, JavaScriptMethod>();
            ClassStaticInitializers  = new Dictionary <string, JavaScriptMethod>();
            GlobalInitializer        = new JavaScriptMethod(voidFuncType);
            EntryPointClass          = null;
            EntryPointFunctionName   = null;
            GlobalNativeCodeSnippets = new List <string>();
        }
Пример #7
0
        private void GenerateClass(StringBuilder output, ClepsClass clepsClass)
        {
            FunctionClepsType voidFuncType = new FunctionClepsType(new List <ClepsType>(), VoidClepsType.GetVoidType());

            EnsureNamespaceExists(output, clepsClass);
            output.AppendLine(JavaScriptCodeParameters.TOPLEVELNAMESPACE + "." + clepsClass.FullyQualifiedName + " = function() {");
            {
                clepsClass.MemberVariables.ToList().ForEach(kvp => output.AppendFormat("\tthis.{0} = undefined;\n", kvp.Key));

                output.AppendFormat("\tthis.{0}();\n", JavaScriptCodeParameters.GetMangledFunctionName("classInitializer", voidFuncType));
                output.AppendFormat("\t{0}.{1}.{2}();\n", JavaScriptCodeParameters.TOPLEVELNAMESPACE, clepsClass.FullyQualifiedName, JavaScriptCodeParameters.GetMangledFunctionName("classStaticInitializer", voidFuncType));
            }
            output.AppendLine("};");

            GenerateMethodWithBody(output, clepsClass.FullyQualifiedName, "classInitializer", voidFuncType, false, ClassInitializers[clepsClass.FullyQualifiedName]);
            GenerateMethodWithBody(output, clepsClass.FullyQualifiedName, "classStaticInitializer", voidFuncType, true, ClassStaticInitializers[clepsClass.FullyQualifiedName]);
        }
Пример #8
0
        public void Output(string directoryName, string fileNameWithoutExtension, CompileStatus status)
        {
            StringBuilder output = new StringBuilder();

            InitializeOutput(output);

            foreach (var nativeCodeSnippet in GlobalNativeCodeSnippets)
            {
                output.AppendLine(nativeCodeSnippet);
            }

            foreach (var clepsClass in ClassesLoaded)
            {
                GenerateClass(output, clepsClass.Value);
            }

            output.AppendLine(GlobalInitializer.GetMethodBodyWithoutDeclaration());

            FunctionClepsType voidFuncType = new FunctionClepsType(new List <ClepsType>(), VoidClepsType.GetVoidType());

            foreach (var clepsType in CompilerConstants.SystemSupportedTypes)
            {
                output.AppendFormat("{0}.{1}.{2}();\n", JavaScriptCodeParameters.TOPLEVELNAMESPACE, clepsType.GetClepsTypeString(), JavaScriptCodeParameters.GetMangledFunctionName("classStaticInitializer", voidFuncType));
            }

            if (!String.IsNullOrWhiteSpace(EntryPointClass) && !String.IsNullOrWhiteSpace(EntryPointFunctionName))
            {
                output.AppendFormat("{0}.{1}.{2}();\n", JavaScriptCodeParameters.TOPLEVELNAMESPACE, EntryPointClass, JavaScriptCodeParameters.GetMangledFunctionName("classStaticInitializer", voidFuncType));
                output.AppendFormat("{0}.{1}.{2}();\n", JavaScriptCodeParameters.TOPLEVELNAMESPACE, EntryPointClass, JavaScriptCodeParameters.GetMangledFunctionName(EntryPointFunctionName, voidFuncType));
            }

            var outputFileName = Path.Combine(directoryName, fileNameWithoutExtension + ".js");

            File.WriteAllText(outputFileName, output.ToString());
        }