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); }
public sealed override object VisitTypenameAndVoid([NotNull] ClepsParser.TypenameAndVoidContext context) { if (context.typename() != null) { return(Visit(context.typename())); } var ret = VoidClepsType.GetVoidType(); return(ret); }
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); }
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)); }
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>(); }
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]); }
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()); }