public void Parse(ref string[] program) { string token = ParseUtils.PeekToken(program); if (token.Equals("(", StringComparison.Ordinal)) { token = ParseUtils.GetToken(ref program); do { Argument arg = new Argument(); token = ParseUtils.GetToken(ref program); if (token.Equals("float", StringComparison.Ordinal)) { arg._Type = VarType.varFloat; } else if (token.Equals("vec", StringComparison.Ordinal)) { arg._Type = VarType.varVector; } else { throw new ParseException("Expected type of parameter (float OR vec), not" + token); } arg._Name = ParseUtils.GetToken(ref program); WooScript.ValidateName(arg._Name); _Arguments.Add(arg); token = ParseUtils.GetToken(ref program); } while (token.Equals(",", StringComparison.Ordinal)); if (!token.Equals(")", StringComparison.Ordinal)) { throw new ParseException("Expected \")\" but found \""+token+"\" instead. :("); } } foreach (Argument a in _Arguments) a.Add(); block.Parse(ref program); foreach (Argument a in _Arguments) a.Remove(); }
public void ParseProgram(ref string[] program) { string token; // pre parse string[] preprogram = program.Clone() as string[]; do { token = ParseUtils.GetToken(ref preprogram); if (string.Compare(token, "rule", true) == 0) { string rulename = ParseUtils.GetToken(ref preprogram); _Log.AddMsg("Preparser found rule " + rulename); RulePrototype ruleproto = new RulePrototype(rulename); string itoken = ParseUtils.PeekToken(preprogram); if (itoken.Equals("(", StringComparison.Ordinal)) { itoken = ParseUtils.GetToken(ref preprogram); do { itoken = ParseUtils.GetToken(ref preprogram); // type Argument arg = new Argument(); if (itoken.Equals("float", StringComparison.Ordinal)) { arg._Type = VarType.varFloat; } else if (itoken.Equals("vec", StringComparison.Ordinal)) { arg._Type = VarType.varVector; } else { throw new ParseException("Expected type of parameter (float OR vec), not" + itoken); } arg._Name = ParseUtils.GetToken(ref preprogram); // name ruleproto._Args.Add(arg); itoken = ParseUtils.GetToken(ref preprogram); // , or ) } while (itoken.Equals(",", StringComparison.Ordinal)); } _RulePrototypes.Add(ruleproto); ConsumeRule(ref preprogram); } else if (string.Compare(token, "shader", true) == 0) { string shadername = ParseUtils.GetToken(ref preprogram); _Log.AddMsg("Preparser found shader " + shadername); _ShaderNames.Add(shadername); ConsumeRule(ref preprogram); } else { if (token.Length > 0) throw new ParseException("Global statements must start with \"rule\"."); } } while (token.Length > 0); // full parse do { token = ParseUtils.GetToken(ref program); if (string.Compare(token, "rule", true) == 0) { string rulename = ParseUtils.GetToken(ref program); _Log.AddMsg("Found rule " + rulename); Rule newRule = new Rule(rulename); _Log.Indent(); newRule.Parse(ref program); _Log.UnIndent(); _Rules.Add(newRule); } else if (string.Compare(token, "shader", true) == 0) { string shadername = ParseUtils.GetToken(ref program); _Log.AddMsg("Found shader " + shadername); Shader newShader = new Shader(shadername); _Log.Indent(); newShader.Parse(ref program); _Log.UnIndent(); _Shaders.Add(newShader); } else { if (token.Length>0) throw new ParseException("Global statements must start with \"rule\"."); } } while (token.Length > 0); // rule rulename { statement* } // statement = floatvar aop floatrhs | vecvar aop vecexpr | nfun ( args ) // args = (rulename|floatexpr|vecexpr)* // floatexpr = ( floatexpr ) | num op floatexpr | ffun(args) op floatexpr | num | ffun(args) | floatvar // num = 0.x | vec.sel // vecexpr = Vec(floatexpr, floatexpr, floatexpr) | vec op vecexpr | vfun ( args ) // vec = vec(x,y,z) | vec(x,y,z).rep }