public override IEnumerator<RantAction> Run(Sandbox sb) { if (sb.Objects[Name] == null) throw new RantRuntimeException(sb.Pattern, _name, $"The subroutine '{Name}' does not exist."); var sub = (RADefineSubroutine)sb.Objects[Name].Value; if (sub.Parameters.Keys.Count != Arguments.Count) throw new RantRuntimeException(sb.Pattern, _name, "Argument mismatch on subroutine call."); var action = sub.Body; var args = new Dictionary<string, RantAction>(); var parameters = sub.Parameters.Keys.ToArray(); for (var i = 0; i < Arguments.Count; i++) { if (sub.Parameters[parameters[i]] == SubroutineParameterType.Greedy) { sb.AddOutputWriter(); yield return Arguments[i]; var output = sb.Return(); args[parameters[i]] = new RAText(_name, output.Main); } else args[parameters[i]] = Arguments[i]; } sb.SubroutineArgs.Push(args); yield return action; sb.SubroutineArgs.Pop(); yield break; }
public override IEnumerator <RantAction> Run(Sandbox sb) { if (_inModule) { if (!sb.Modules.ContainsKey(Name)) { throw new RantRuntimeException( sb.Pattern, _name, $"The module '{Name}' does not exist or has not been imported." ); } if (sb.Modules[Name][_moduleFunctionName] == null) { throw new RantRuntimeException( sb.Pattern, _name, $"The function '{_moduleFunctionName}' cannot be found in the module '{Name}'." ); } } else if (sb.Objects[Name] == null) { throw new RantRuntimeException(sb.Pattern, _name, $"The subroutine '{Name}' does not exist."); } var sub = (RADefineSubroutine)(_inModule ? sb.Modules[Name][_moduleFunctionName] : sb.Objects[Name].Value); if (sub.Parameters.Keys.Count != Arguments.Count) { throw new RantRuntimeException(sb.Pattern, _name, "Argument mismatch on subroutine call."); } var action = sub.Body; var args = new Dictionary <string, RantAction>(); var parameters = sub.Parameters.Keys.ToArray(); for (var i = 0; i < Arguments.Count; i++) { if (sub.Parameters[parameters[i]] == SubroutineParameterType.Greedy) { sb.AddOutputWriter(); yield return(Arguments[i]); var output = sb.Return(); args[parameters[i]] = new RAText(_name, output.Main); } else { args[parameters[i]] = Arguments[i]; } } sb.SubroutineArgs.Push(args); yield return(action); sb.SubroutineArgs.Pop(); yield break; }
private IEnumerable<Parselet> BlockWeight(Token<R> token) { Token<R> funcToken = null; var actions = new List<RantAction>(); while (!reader.End) { funcToken = reader.ReadToken(); if (funcToken.ID == R.RightParen) { reader.SkipSpace(); if (!actions.Any()) compiler.SyntaxError(funcToken, "Expected weight value"); RantAction weightAction; // probably a number if (actions[0] is RAText) { if (actions.Count > 1) { if (!(actions[1] is RAText) || ((RAText)actions[1]).Text != "." || actions.Count != 3) compiler.SyntaxError(actions[1].Range, "Invalid block weight value."); weightAction = new RAText(actions[0].Range, (actions[0] as RAText).Text + (actions[1] as RAText).Text + (actions[2] as RAText).Text); } else weightAction = actions[0]; } else weightAction = new RASequence(actions, funcToken); AddToOutput(weightAction); yield break; } yield return Parselet.GetParselet(funcToken, actions.Add); } // TODO: this token is "our" (the one that result is us being yielded) token. maybe have the 'fromToken' passed? compiler.SyntaxError(token, "Unterminated function: unexpected end of file"); }