public Level Analyze(Session ses, Tokens tokens) { Level lvl = new Level(this); ses.Leaf = lvl; tokens.SetLevel(lvl); // Match parameters for (int i = 0; i < Parameters.Count; i++) { Parameter p = Parameters[i]; p.Update(ses); MatchResult res = p.Analyze(ses, tokens, lvl); // if no tokens left, leave unmatched alone (to match previous params) // else, update so that later ones would not go back before the param // this also ensures auto completion even if the word is already completed // TODO: unmatched might jump back (e.g. "task name -s") if (tokens.Count == 0) break; if (res == MatchResult.Matched) lvl.FirstUnmatchedParam = i + 1; else if (res == MatchResult.Extensible) lvl.FirstUnmatchedParam = i; else if (p.Required) // implied "Failed" { // TODO: handle "required" ses.Error(new ArgumentException($"{p} requires a valid value")); break; } } // Raise event InputChanged?.Invoke(this, new ScriptEventArgs(ses, lvl.Arguments, lvl.Child)); return lvl; }