private static FunctionElement CreateMain() { var symbols = LanguageSymbols.Instance; LanguageFunction functionInfo = new LanguageFunction(); functionInfo.Name = "!_Main"; functionInfo.Arguments = new List <LanguageFunction.FunctionArg>(); functionInfo.ReturnTypes = new List <LanguageType>(); symbols.AddUserFunction(functionInfo); FunctionElement funcElement = new FunctionElement(); funcElement.Info = functionInfo; StatementListElement statements = new StatementListElement(); funcElement.AddChild(statements); FunctionCallElement callElement = new FunctionCallElement(); LanguageFunction mainFuncInfo = null; try { mainFuncInfo = symbols.GetFunction("Main", new List <string>()); } catch (CompilationException) { Compilation.WriteError("Main() wasn't found. Did you forget it?", -1); } callElement.FunctionInfo = mainFuncInfo; callElement.CallArguments = new List <ValueElement>(); statements.AddChild(callElement); SingleGenOpElement exitElement = new SingleGenOpElement(); exitElement.Operation = new GenOp { Code = GenCodes.Exit, ArgCount = 0 }; statements.AddChild(exitElement); return(funcElement); }
/// <summary> /// Build expression value. It's called from ParseExpression /// </summary> /// <param name="lexemes">List of lexemes</param> /// <param name="pos">Position of current parsed lexeme</param> /// <param name="flags">Control flags. ExpressionFlags.None to ignore all flags</param> /// <param name="elem">Builded value element. null if it's not a value</param> /// <returns>Position of a next lexeme</returns> private int ParseExpressionValue(List <Lexeme> lexemes, int pos, ExpressionFlags flags, out ValueElement elem) { MultipleValElement multipleVals = new MultipleValElement(); if (lexemes[pos].Source == "(") { List <ValueElement> values; pos = ExtractSeparatedExpressions(lexemes, pos, flags | ExpressionFlags.ForbidMultiple, out values); if (pos >= (lexemes.Count - 1)) { Compilation.WriteError("Unexpected end of file. Did you forget ')' and ';' ?", -1); } foreach (var i in values) { multipleVals.AddValue(i); } } //"(" else if (lexemes[pos].Code == Lexeme.CodeType.Number) { var val = new ConstValElement { Type = m_symbols.GetTypeOfConstVal(lexemes[pos].Source), Value = lexemes[pos].Source }; ++pos; elem = val; return(pos); } else if (m_currentFunction.HasVariable(lexemes[pos].Source) && lexemes[pos + 1].Source != "(") { var val = new GetVariableElement() { VarName = lexemes[pos].Source, VarType = m_currentFunction.GetVariable(lexemes[pos].Source).VarType, ResultOfGeneration = GetVariableElement.GenerateOptions.Value }; ++pos; elem = val; return(pos); } else if (m_symbols.HasFunctionWithName(lexemes[pos].Source)) { FunctionCallElement callElement = new FunctionCallElement(); string funcName = lexemes[pos].Source; ++pos; List <ValueElement> values; if (lexemes[pos + 1].Source == ")") //fucntion without arguments { values = new List <ValueElement>(); pos += 2; //'(' ')' } else { pos = ExtractSeparatedExpressions(lexemes, pos, flags | ExpressionFlags.AllowAutoDefault, out values); } if (values.Count == 1 && values[0].NumberOfBranches > 1) { values = values[0].Children().Select(child => (ValueElement)child).ToList(); } callElement.FunctionInfo = m_symbols.GetFunction( funcName, values.Select(val => val?.ResultType.ResultTypes[0].Name).ToList()); for (int i = 0, end = values.Count; i < end; ++i) { if (values[i] == null) { values[i] = callElement.FunctionInfo.Arguments[i].DefaultVal; } } callElement.CallArguments = values; elem = callElement; return(pos); } else if (lexemes[pos].Source == "default") { ++pos; if (lexemes[pos].Source == "(") { Compilation.Assert(flags.HasFlag(ExpressionFlags.AllowDefaultValue), "Default type value keyword is used but it isn't allowed here.", lexemes[pos].Line); ++pos; //skip '(' string typeName = lexemes[pos].Source; //TODO: namespaces ConstValElement constVal = m_symbols.GetDefaultVal(typeName); elem = new ConstValElement { Type = constVal.Type, Value = constVal.Value }; ++pos; ++pos; //skip ')' } else { Compilation.Assert(flags.HasFlag(ExpressionFlags.AllowAutoDefault), "Auto default keyword is used but it isn't allowed here.", lexemes[pos].Line); elem = null; } return(pos); } else //Not a value { elem = null; return(pos); } elem = multipleVals; return(pos); }