public bool TryBuildExpression(ASTBuilder treeBuilder, FunctionToken functionToken, Stack <Token> stack, ParameterExpression p, out Expression output) { if (functionToken.ParameterCount == 0) { throw new XPressionException(functionToken.Source, "format requires at least one argument", functionToken.Position); } var args = new List <Expression>(); for (var i = 0; i < functionToken.ParameterCount; i++) { args.Add(treeBuilder.PopExpression(stack, p)); } args.Reverse(); // reverse stack order output = Expression.Call( MemberTokens.String.FormatWithProvider, Expression.Constant(CultureInfo.InvariantCulture), args[0], Expression.NewArrayInit( typeof(object), args.Skip(1).Select(e => e.Type == typeof(object) ? e : Expression.Convert(e, typeof(object))) ) ); return(true); }
public object Execute(KarinEngine engine, FunctionToken token, object pipedObj) { var args = token.Arguments; if (!(2 <= args.Length || args.Length <= 3)) { throw new KarinException($"{Name}関数の引数の数が不正です。"); } //条件を演算 var sw = engine.Ride(args[0]); if (!(sw is bool)) { throw new KarinException($"{Name}関数の条件を評価できません。"); } //どちらかを実行 if ((bool)sw) { return(engine.Ride(args[1])); } else { return(args.Length == 3 ? engine.Ride(args[2]) : null); } }
public object Execute(KarinEngine engine, FunctionToken token, object pipedObj) { var args = token.Arguments; if (args.Length != 2) { throw new KarinException($"{Name}関数の引数の数が不正です。"); } //回数条件 var co = engine.Ride(args[0]); //繰り返し実行 object ret = null; for (var c = 0; c < (int)co; c++) { ret = engine.Ride(args[1]); if (ret is ReturnedObject) { break; } } return(ret); }
public object Execute(KarinEngine engine, FunctionToken token, object pipedObj) { if (!((token.IsPipe && token.Arguments.Length == 0) || (!token.IsPipe && token.Arguments.Length == 1))) { throw new KarinException($"{Name}関数の引数の数が不正です。"); } var arg = token.IsPipe ? pipedObj : engine.Ride(token.Arguments[0]); if (!(arg is string)) { throw new KarinException($"{Name}関数の引数が文字列ではありません。"); } var s = (string)arg; var sb = new StringBuilder(s.Length); int pre = 0; var ptn = new Regex(@"{\s*(\$\$?[^\s\$\{\}]+)\s*}"); foreach (Match m in ptn.Matches(s)) { var val = engine.Eval(m.Value); sb.Append(s.Substring(pre, m.Index - pre)); sb.Append(val); pre = m.Index + m.Length; } sb.Append(s.Substring(pre, s.Length - pre)); return(sb.ToString()); }
private bool TryCompileAliasedFunction(MessageScriptParser.TokenContext context, string tagId, out FunctionToken functionToken) { LogContextInfo(context); functionToken = new FunctionToken(); var functionWasFound = false; foreach (var library in Library.MessageScriptLibraries) { var function = library.Functions.SingleOrDefault(x => x.Name == tagId); if (function == null) { continue; } var arguments = new List <short>(); for (var i = 0; i < function.Parameters.Count; i++) { if (!TryParseShortIntLiteral(context, "Expected function argument", () => context.IntLiteral(i), out var argument)) { return(false); } arguments.Add(argument); } functionToken = new FunctionToken(library.Index, function.Index, arguments); functionWasFound = true; break; } return(functionWasFound); }
public object Execute(KarinEngine engine, FunctionToken token, object pipedObj) { var args = token.Arguments; if (args.Length != 2) { throw new KarinException($"{Name}関数の引数の数が不正です。"); } object ret = null; while (true) { object loop = engine.Ride(args[0]); if (!(loop is bool)) { throw new KarinException($"{Name}関数の条件を評価できません。"); } if ((bool)loop == false) { break; } ret = engine.Ride(args[1]); if (ret is ReturnedObject) { break; } } return(ret); }
private static OnStatement readOn(TokenCollection stream) { OnFunctionPrimitive token = stream.GetNextToken() as OnFunctionPrimitive; if (token == null) { throw new HspLogicalLineException("on条件分岐行:条件分岐プリミティブ以外からスタート"); } //式がないこともあるかもしれない(実行時エラー) if (stream.NextIsEndOfLine) { return(new OnStatement(token, null, null)); } //式を読む。goto/gosubがないこともあるかもしれない(実行時エラー) ExpressionToken exp = CodeTokenFactory.ReadExpression(stream); if (stream.NextIsEndOfLine) { return(new OnStatement(token, exp, null)); } //goto/gosub関数を読む。goto/gosub以外でもコンパイルは通る(実行時エラー) //この関数には()がつかない。 FunctionToken func = CodeTokenFactory.ReadFunction(stream, false); if (stream.NextIsEndOfLine) { return(new OnStatement(token, exp, func)); } //まだあまってたらエラーね。 throw new HspLogicalLineException("on条件分岐行:余分なトークンがある"); }
public void EqualsDiffTypeTest() { var token = new FunctionToken(Functions.Sine, 1); Assert.False(token.Equals(1)); Assert.NotEqual((object)1, token); }
/// <summary> /// Make a function node from a parsed function token. /// </summary> /// <param name="tok"></param> public FunctionNode(FunctionToken tok) { Name = tok.Name; TopArguments = tok.TopArguments; BottomArguments = tok.BottomArguments; Tiebreaker = tok.Range.Max; }
public void EqualsNullTest() { var token = new FunctionToken(Functions.Sine, 1); Assert.False(token.Equals(null)); Assert.NotNull(token); }
public static double Log10(FunctionToken func, Evaluator evaluator) { var args = func.Arguments; var num = args[0].Evaluate(evaluator); return(Math.Log10(num)); }
public RawFunctionNode(FunctionToken functionName, ArgListNode args, Type returnType, bool doNotCache) { _functionName = functionName; Args = args; ReturnType = returnType; DoNotCache = doNotCache; }
public void EqualsSameObjectTest() { var token = new FunctionToken(Functions.Sine, 1); Assert.True(token.Equals(token)); Assert.Equal(token, token); }
public static double Atan(FunctionToken func, Evaluator evaluator) { var args = func.Arguments; var num = args[0].Evaluate(evaluator); return(Math.Atan(num.ToRadians(evaluator.Settings.Mode))); }
public static double GradToRad(FunctionToken func, Evaluator evaluator) { var args = func.Arguments; var num = args[0].Evaluate(evaluator); return(num.ToRadians(Mode.Grad)); }
public bool TryBuildExpression(ASTBuilder treeBuilder, FunctionToken functionToken, Stack <Token> stack, ParameterExpression p, out Expression output) { var rightToken = stack.Pop(); // must be a constant string var target = treeBuilder.PopExpression(stack, p); if (target.IsNullConstant()) { output = Expression.Convert(Expression.Constant(null), typeof(bool?)); return(true); } Type type; try { type = treeBuilder.Grammar.GetType(rightToken.Lexeme); } catch (Exception ex) { throw new XPressionException(functionToken.Source, "Invalid type: " + rightToken.Lexeme, rightToken.Position, ex); } if ((!target.Type.IsValueType || target.Type.IsNullable()) && type.IsValueType && !type.IsNullable()) { type = typeof(Nullable <>).MakeGenericType(type); } output = Expression.TypeEqual(target, type); return(true); }
public void TestTokenProperties() { IdentifierToken functionName = new IdentifierToken("function"); FunctionToken result = new FunctionToken(0, functionName); Assert.AreEqual(functionName, result.FunctionName); }
public FunctionBlock(IBlock parent, BlockType type, TrackingToken start, ITextSnapshot textSnapshot, FunctionToken name) : base(parent, type, start, textSnapshot) { Name = name; Parameters = new List <IDefinitionToken>(); parent.AddToken(name); name.FunctionBlock = this; }
public void EqualsDiffFuncTest() { var token1 = new FunctionToken(Functions.Sine, 1); var token2 = new FunctionToken(Functions.Cosine, 1); Assert.False(token1.Equals(token2)); Assert.NotEqual(token1, token2); }
private void CheckDefinition(FunctionToken def) { if (def.Name != "Def") { throw new ParseException("Function definitions must start with a call named Def, like this: " + example) { FunctionToken = def } } ; if (def.TopArguments.Length == 0) { throw new ParseException("Function definitions must have at leat one argument- the name: " + example) { FunctionToken = def } } ; foreach (Argument arg in def.TopArguments.Concat(def.BottomArguments)) { if (!(arg is FunctionArg)) { throw new ParseException("Incorrect formal parameter declaration {0}. All parameters must have alphabetic names and no quotes.", arg) { FunctionToken = def } } ; } TopArguments = def.TopArguments.Skip(1).Cast <FunctionArg>().ToArray(); BottomArguments = def.BottomArguments.Cast <FunctionArg>().ToArray(); string functionName = def.TopArguments[0].GetAs <string>(); if (functionName == "...") { throw new ParseException("... cannot be the name of a function. Function names consist of letters only.") { FunctionToken = def }; } else { Name = functionName; } // if Main doesn't have any arguments if (Name == "Main" && TopArguments.Length == 0) { TopArguments = new FunctionArg[] { FunctionArg.TryParseArg("...") }; } } } }
public override Token getToken() { FunctionToken token = new FunctionToken(); token.setValue(sbCode.ToString()); token.setType(TokenType.Function); return(token); }
// C# equivalents: // if(test,body) => return test ? body() : true; // if(test,trueBody,falseBody) => return test ? trueBody() : falseBody(); // if parametercount==2 (falseBody is omitted), then the falseBody always // returns true (so then the trueBody MUST return a boolean value as well) public bool TryBuildExpression(ASTBuilder treeBuilder, FunctionToken functionToken, Stack <Token> stack, ParameterExpression p, out Expression output) { var ifFalse = functionToken.ParameterCount >= 3 ? treeBuilder.PopExpression(stack, p) : Expression.Constant(true); var ifTrue = treeBuilder.PopExpression(stack, p); var test = treeBuilder.PopExpression(stack, p); output = Expression.Condition(test.Convert <bool>(), ifTrue, ifFalse); return(true); }
public AccessMethodNode(FunctionToken fToken, ArgsListNode args, ArgsListNode extraAggregateArguments, MethodInfo method = (MethodInfo)null, string alias = "") { FToken = fToken; Arguments = args; ExtraAggregateArguments = extraAggregateArguments; Method = method; Alias = alias; Id = $"{nameof(AccessMethodNode)}{alias}{fToken.Value}{args.Id}"; }
public void FunctionParsingWorks(string test, string name, int argCount) { foreach (string teststr in new[] { test, @"\." + test, test + "./", @"\." + test + "./" }) { FunctionToken f = new FunctionToken(teststr, 0, teststr.Length); Assert.AreEqual(name, f.Name); Assert.AreEqual(argCount, f.TopArguments.Length); } }
private Expression BuildArrayAccessExpression(FunctionToken token, Expression array, Stack <Token> stack, ParameterExpression p) { var args = new List <Expression>(); for (var i = 0; i < token.ParameterCount; i++) { args.Add(PopExpression(stack, p)); } args.Reverse(); return(Expression.ArrayAccess(array, args)); }
/// <summary> /// 命令行 /// </summary> /// <param defaultName="primitives"></param> /// <returns></returns> private static Command readCommand(TokenCollection stream) { //実態はCodeTokenFactoryに任せる //命令には(関数と違って)括弧はいらない FunctionToken func = CodeTokenFactory.ReadFunction(stream, false); if (stream.NextIsEndOfLine) { return(new Command(func)); } throw new HspLogicalLineException("命令行:余分なトークンがある"); }
public object Execute(KarinEngine engine, FunctionToken token, object pipedObj) { if (token.Arguments.Length != 1) { throw new KarinException($"{Name}関数の引数の数が不正です。"); } var ptn = new System.Text.RegularExpressions.Regex($@"{token.Name}\s*\[([\s\S]*)\]"); var mc = ptn.Match(token.Text); return(mc.Groups[1].Value); }
private bool TryParseFunction(string expression, int i, out FunctionToken functionToken) { functionToken = default(FunctionToken); foreach (var function in Functions) { if (function.TryParse(expression, i)) { functionToken = function; return(true); } } return(false); }
public static double Log(FunctionToken func, Evaluator evaluator) { var args = func.Arguments; var a = args[0].Evaluate(evaluator); if (args.Length == 1) { return(Math.Log(a)); } var @base = args[1].Evaluate(evaluator); return(Math.Log(a, @base)); }
public void Decompile(FunctionToken token) { if (Library != null) { var library = Library.MessageScriptLibraries.FirstOrDefault(x => x.Index == token.FunctionTableIndex); if (library != null) { var function = library.Functions.FirstOrDefault(x => x.Index == token.FunctionIndex); if (function != null) { if (function.Semantic == MessageScriptLibraryFunctionSemantic.Unused && OmitUnusedFunctions) { return; } if (!string.IsNullOrWhiteSpace(function.Name)) { WriteOpenTag(FormatIdentifier(function.Name)); for (var i = 0; i < function.Parameters.Count; i++) { var argument = function.Parameters[i]; WriteTagArgument(token.Arguments[i].ToString()); } WriteCloseTag(); return; } } } } if (token.Arguments.Count == 0) { WriteTag("f", token.FunctionTableIndex.ToString(), token.FunctionIndex.ToString()); } else { WriteOpenTag("f"); WriteTagArgument(token.FunctionTableIndex.ToString()); WriteTagArgument(token.FunctionIndex.ToString()); foreach (var tokenArgument in token.Arguments) { WriteTagArgument(tokenArgument.ToString()); } WriteCloseTag(); } }
private static QueryExpression ParseFunction(QueryExpression subQuery, List<Token> tokens, int startToken, int numTokens, FunctionToken functionToken) { if (!(tokens[startToken] is VariableToken)) throw new CSExpressionException("Function call " + functionToken.Function + " called with incorrect parameters"); QueryExpression newQuery = (QueryExpression) EvalVariable(((VariableToken) tokens[startToken]).Variable, subQuery); string fieldExpression; switch (functionToken.Function) { case "HAS": fieldExpression = "*"; break; case "COUNT": fieldExpression = "count(*)"; break; case "COUNTDISTINCT": fieldExpression = "count(distinct " + newQuery.FieldName + ")"; break; default: fieldExpression = functionToken.Function + "(" + newQuery.FieldName + ")"; break; } if (numTokens > 1) { if (!(tokens[startToken + 1] is OperatorToken)) throw new CSExpressionException("Expected WHERE"); OperatorToken whereToken = (OperatorToken) tokens[startToken + 1]; if (whereToken.Operator.ToUpper() != "WHERE") throw new CSExpressionException("Expected WHERE"); if (numTokens < 3) throw new CSExpressionException("Expected expression after WHERE"); newQuery.Expression += " AND "; newQuery = Parse(newQuery, tokens, startToken + 2, numTokens - 2); } string selectSql = newQuery.Table.Schema.DB.BuildSelectSQL(newQuery.Table.TableName, newQuery.Table.TableAlias, new[] { fieldExpression }, null, newQuery.Joins.BuildJoinExpressions(), newQuery.Expression, null, 1, 0, false, false); if (functionToken.Function == "HAS") subQuery.Expression += "EXISTS "; subQuery.Expression += "(" + selectSql + ")"; return subQuery; }
private static Token[] GetInfixTokens(string term) { //Leerzeichen entfernen und in Kleinbuchstaben konvertieren term = term.Replace(" ", string.Empty).ToLowerInvariant(); var tokens = new List<Token>(); //mit RegEx alle Zahlen aussortieren var numbers = parserRegEx.Matches(term); term = parserRegEx.Replace(term, "1"); var sb = new StringBuilder(term); //Term in Tokens teilen var numberIndex = 0; while (sb.Length > 0) { var validToken = false; //Zahlen prüfen if (sb.StartsWith("1")) { var t = new NumberToken(); t.ParseFromString(numbers[numberIndex].Groups["number"].Value); tokens.Add(t); numberIndex++; //term = ReduceString(term, 1); sb.Remove(0, 1); validToken = true; } //Operatoren prüfen if (!validToken) for (int i = 0; i < operators.Length; i++) { var token = operators[i]; if (sb.StartsWith(token)) { var t = new OperatorToken(); if ((token == '+' || token == '-') && (tokens.Count == 0 || tokens.Last().GetName() == "(")) //Vorzeichen { if (token == '-') t.ParseFromString("!"); } else t.ParseFromString(token.ToString()); tokens.Add(t); //term = ReduceString(term, 1); sb.Remove(0, 1); validToken = true; break; } } //Funktionen prüfen if (!validToken) for (int i = 0; i < functions.Length; i++) { var token = functions[i]; if (sb.StartsWith(token)) { var t = new FunctionToken(); t.ParseFromString(token); tokens.Add(t); //term = ReduceString(term, token.Length); sb.Remove(0, token.Length); validToken = true; break; } } //Rest prüfen if (!validToken) { if (sb.StartsWith("pi")) //Pi { var t = new NumberToken(); t.ParseFromString(System.Math.PI.ToString()); tokens.Add(t); //term = ReduceString(term, 2); sb.Remove(0, 2); } else if (sb.StartsWith("e")) //e { var t = new NumberToken(); t.ParseFromString(System.Math.E.ToString()); tokens.Add(t); //term = ReduceString(term, 1); sb.Remove(0, 1); } else if (sb.StartsWith("(")) //öffnende Klammer { var t = new SpecialToken(); t.ParseFromString("("); tokens.Add(t); //term = ReduceString(term, 1); sb.Remove(0, 1); } else if (sb.StartsWith(")")) //schließende Klammer { var t = new SpecialToken(); t.ParseFromString(")"); tokens.Add(t); //term = ReduceString(term, 1); sb.Remove(0, 1); } else if (sb.StartsWith(";")) //Argumenttrennzeichen { var t = new SpecialToken(); t.ParseFromString(";"); tokens.Add(t); //term = ReduceString(term, 1); sb.Remove(0, 1); } else //Token nicht bekannt throw new ArgumentException("Dieser Term enthält einen ungültigen Token."); } } return tokens.ToArray(); }