public void Parse(ref string[] program) { _Target = ParseUtils.PeekToken(program); bool isFloatVar = ShaderScript.IsFloatVar(_Target); bool isVectorVar = ShaderScript.IsVectorVar(_Target); bool isNullFunc = ShaderScript.IsNullFunction(_Target); if (!isFloatVar && !isVectorVar && !isNullFunc) { throw new ParseException("Expected \"" + _Target + "\" to be a float or vector variable or a non-return function"); } if (isFloatVar || isVectorVar) { _Target = ParseUtils.GetToken(ref program); _IsNull = false; WooScript._Log.AddMsg("Found target variable \"" + _Target + "\""); WooScript._Log.Indent(); _AssignOp = ParseUtils.GetToken(ref program); if (!ShaderScript.IsAssignOp(_AssignOp)) { throw new ParseException("Expected \"" + _AssignOp + "\" to be an assignment operation"); } } _Argument = ShaderScript.ParseExpression(ref program); }
public static void ValidateFunction(ScriptElement func) { bool foundFunction = false; bool validNumParams = false; bool validTypeParams = false; foreach (DistFunc df in _DistFunc) { if (df._Name.Equals(func._String, StringComparison.Ordinal)) { foundFunction = true; if (df._DistParams.Count == func._Arguments.Count) { validNumParams = true; bool functionParamsValid = true; for (int i = 0; i < df._DistParams.Count; i++) { if (df._DistParams.ElementAt(i)._Type != func._Arguments.ElementAt(i)._Type) { functionParamsValid = false; } } if (functionParamsValid) { validTypeParams = true; func._Type = df._ReturnType; } } } } if (!foundFunction) { throw new ParseException("Missing distance function looking up \"" + func._String + "\""); } if (!validNumParams) { throw new ParseException("No matching version of function \"" + func._String + "\" found expecting " + func._Arguments.Count + " parameters"); } if (!validTypeParams) { throw new ParseException("Type mismatch on args for function \"" + func._String + "\""); } }
public static ScriptElement ParseExpression(ref string[] program) { ScriptElement ret = new ScriptElement(); string token = ParseUtils.PeekToken(program); ret._Reorderable = false; if (token.Equals("-", StringComparison.Ordinal)) { token = ParseUtils.GetToken(ref program); token += ParseUtils.PeekToken(program); } if (token.Equals("(", StringComparison.Ordinal)) { token = ParseUtils.GetToken(ref program); ret = ParseExpression(ref program); ret._Reorderable = false; token = ParseUtils.GetToken(ref program); if (!token.Equals(")", StringComparison.Ordinal)) { throw new ParseException("Missing closebracket on bracketed expression, found" + token); } } else if (IsFloatVar(token)) { token = ParseUtils.GetToken(ref program); ret._Type = SEType.FloatVar; ret._String = token; } else if (IsVectorVar(token)) { token = ParseUtils.GetToken(ref program); ret._Type = SEType.VectorVar; ret._String = token; } else if (IsFloatNum(token)) { string chuck = ParseUtils.GetToken(ref program); ret._Type = SEType.FloatVar; ret._String = token; } else if (token.Equals("{")) { ret._Type = SEType.CodeBlock; ret._Codeblock = new CodeBlock(); ret._Codeblock.Parse(ref program); } else if (token.IndexOf('.') > -1) { token = ParseUtils.GetToken(ref program); int dotPosition = token.IndexOf('.'); ret._Type = SEType.VectorVar; ret._String = token.Substring(0, dotPosition); ScriptElement getter = new ScriptElement(); string index = token.Substring(dotPosition + 1); if (index.Equals("x", StringComparison.Ordinal)) { getter._String = "getx"; } else if (index.Equals("y", StringComparison.Ordinal)) { getter._String = "gety"; } else if (index.Equals("z", StringComparison.Ordinal)) { getter._String = "getz"; } else { throw new ParseException("Invalid subindex " + index); } getter._Arguments.Add(ret); getter._Type = SEType.FloatVar; ret = getter; } else if (token.Equals("repeat", StringComparison.Ordinal)) { token = ParseUtils.GetToken(ref program); ret._String = token; string openBracket = ParseUtils.PeekToken(program); if (openBracket.Equals("(", StringComparison.Ordinal)) { openBracket = ParseUtils.GetToken(ref program); ret._Arguments.Add(ParseExpression(ref program)); string closeBracket = ParseUtils.GetToken(ref program); if (!closeBracket.Equals(")", StringComparison.Ordinal)) { throw new ParseException("Expected close bracket, found \"" + token + "\""); } } else { throw new ParseException("repeat not followed by number, found \"" + token + "\", usage : repeat(x){}"); } ret._Arguments.Add(ParseExpression(ref program)); } else if (IsFunction(token)) { token = ParseUtils.GetToken(ref program); ret._String = token; string openBracket = ParseUtils.PeekToken(program); if (openBracket.Equals("(", StringComparison.Ordinal)) { openBracket = ParseUtils.GetToken(ref program); ret._Arguments.Add(ParseExpression(ref program)); string comma = ParseUtils.PeekToken(program); while (comma.Equals(",", StringComparison.Ordinal)) { comma = ParseUtils.GetToken(ref program); ret._Arguments.Add(ParseExpression(ref program)); comma = ParseUtils.PeekToken(program); } string closeBracket = ParseUtils.GetToken(ref program); if (!closeBracket.Equals(")", StringComparison.Ordinal)) { throw new ParseException("Expected close bracket, found \"" + token + "\""); } } ValidateFunction(ret); } else { throw new ParseException("Unrecognised token found \"" + token + "\""); } string opCode = ParseUtils.PeekToken(program); if (IsOperator(opCode)) { opCode = ParseUtils.GetToken(ref program); ScriptElement opElement = new ScriptElement(); if (opCode.Equals("+", StringComparison.Ordinal)) { opElement._String = "add"; } if (opCode.Equals("-", StringComparison.Ordinal)) { opElement._String = "sub"; } if (opCode.Equals("*", StringComparison.Ordinal)) { opElement._String = "mul"; } if (opCode.Equals("/", StringComparison.Ordinal)) { opElement._String = "div"; } if (opCode.Equals("%", StringComparison.Ordinal)) { opElement._String = "mod"; } opElement._Type = ret._Type; opElement._Arguments.Add(ret); ScriptElement arg2 = ParseExpression(ref program); opElement._Arguments.Add(arg2); if (arg2._Reorderable) { if (GetPrecedence(opElement._String) < GetPrecedence(arg2._String)) { ScriptElement Arg1Arg1 = ret; ScriptElement Arg2Arg1 = arg2._Arguments.ElementAt(0); ScriptElement Arg2Arg2 = arg2._Arguments.ElementAt(1); arg2._Arguments.Clear(); arg2._Arguments.Add(opElement); arg2._Arguments.Add(Arg2Arg2); opElement._Arguments.Clear(); opElement._Arguments.Add(Arg1Arg1); opElement._Arguments.Add(Arg2Arg1); opElement = arg2; } } ret = opElement; ret._Reorderable = true; ValidateFunction(opElement); } return(ret); }
public void Parse(ref string[] program) { _Target = ParseUtils.PeekToken(program); bool isFloatVar = ShaderScript.IsFloatVar(_Target); bool isVectorVar = ShaderScript.IsVectorVar(_Target); bool isNullFunc = ShaderScript.IsNullFunction(_Target); if (!isFloatVar && !isVectorVar && !isNullFunc) throw new ParseException("Expected \"" + _Target + "\" to be a float or vector variable or a non-return function"); if (isFloatVar || isVectorVar) { _Target = ParseUtils.GetToken(ref program); _IsNull = false; WooScript._Log.AddMsg("Found target variable \"" + _Target + "\""); WooScript._Log.Indent(); _AssignOp = ParseUtils.GetToken(ref program); if (!ShaderScript.IsAssignOp(_AssignOp)) throw new ParseException("Expected \"" + _AssignOp + "\" to be an assignment operation"); } _Argument = ShaderScript.ParseExpression(ref program); }
public static ScriptElement ParseExpression(ref string[] program) { ScriptElement ret = new ScriptElement(); string token = ParseUtils.PeekToken(program); ret._Reorderable = false; if (token.Equals("-", StringComparison.Ordinal)) { token = ParseUtils.GetToken(ref program); token += ParseUtils.PeekToken(program); } if (token.Equals("(", StringComparison.Ordinal)) { token = ParseUtils.GetToken(ref program); ret = ParseExpression(ref program); ret._Reorderable = false; token = ParseUtils.GetToken(ref program); if (!token.Equals(")", StringComparison.Ordinal)) throw new ParseException("Missing closebracket on bracketed expression, found" + token); } else if (IsFloatVar(token)) { token = ParseUtils.GetToken(ref program); ret._Type = SEType.FloatVar; ret._String = token; } else if (IsVectorVar(token)) { token = ParseUtils.GetToken(ref program); ret._Type = SEType.VectorVar; ret._String = token; } else if (IsFloatNum(token)) { string chuck = ParseUtils.GetToken(ref program); ret._Type = SEType.FloatVar; ret._String = token; } else if (token.Equals("{")) { ret._Type = SEType.CodeBlock; ret._Codeblock = new CodeBlock(); ret._Codeblock.Parse(ref program); } else if (token.IndexOf('.') > -1) { token = ParseUtils.GetToken(ref program); int dotPosition = token.IndexOf('.'); ret._Type = SEType.VectorVar; ret._String = token.Substring(0, dotPosition); ScriptElement getter = new ScriptElement(); string index = token.Substring(dotPosition + 1); if (index.Equals("x", StringComparison.Ordinal)) getter._String = "getx"; else if (index.Equals("y", StringComparison.Ordinal)) getter._String = "gety"; else if (index.Equals("z", StringComparison.Ordinal)) getter._String = "getz"; else throw new ParseException("Invalid subindex " + index); getter._Arguments.Add(ret); getter._Type = SEType.FloatVar; ret = getter; } else if (token.Equals("repeat", StringComparison.Ordinal)) { token = ParseUtils.GetToken(ref program); ret._String = token; string openBracket = ParseUtils.PeekToken(program); if (openBracket.Equals("(", StringComparison.Ordinal)) { openBracket = ParseUtils.GetToken(ref program); ret._Arguments.Add(ParseExpression(ref program)); string closeBracket = ParseUtils.GetToken(ref program); if (!closeBracket.Equals(")", StringComparison.Ordinal)) throw new ParseException("Expected close bracket, found \"" + token + "\""); } else { throw new ParseException("repeat not followed by number, found \"" + token + "\", usage : repeat(x){}"); } ret._Arguments.Add(ParseExpression(ref program)); } else if (IsFunction(token)) { token = ParseUtils.GetToken(ref program); ret._String = token; string openBracket = ParseUtils.PeekToken(program); if (openBracket.Equals("(", StringComparison.Ordinal)) { openBracket = ParseUtils.GetToken(ref program); ret._Arguments.Add(ParseExpression(ref program)); string comma = ParseUtils.PeekToken(program); while (comma.Equals(",", StringComparison.Ordinal)) { comma = ParseUtils.GetToken(ref program); ret._Arguments.Add(ParseExpression(ref program)); comma = ParseUtils.PeekToken(program); } string closeBracket = ParseUtils.GetToken(ref program); if (!closeBracket.Equals(")", StringComparison.Ordinal)) throw new ParseException("Expected close bracket, found \"" + token + "\""); } ValidateFunction(ret); } else { throw new ParseException("Unrecognised token found \"" + token + "\""); } string opCode = ParseUtils.PeekToken(program); if (IsOperator(opCode)) { opCode = ParseUtils.GetToken(ref program); ScriptElement opElement = new ScriptElement(); if (opCode.Equals("+", StringComparison.Ordinal)) opElement._String = "add"; if (opCode.Equals("-", StringComparison.Ordinal)) opElement._String = "sub"; if (opCode.Equals("*", StringComparison.Ordinal)) opElement._String = "mul"; if (opCode.Equals("/", StringComparison.Ordinal)) opElement._String = "div"; if (opCode.Equals("%", StringComparison.Ordinal)) opElement._String = "mod"; opElement._Type = ret._Type; opElement._Arguments.Add(ret); ScriptElement arg2 = ParseExpression(ref program); opElement._Arguments.Add(arg2); if (arg2._Reorderable) { if (GetPrecedence(opElement._String) < GetPrecedence(arg2._String)) { ScriptElement Arg1Arg1 = ret; ScriptElement Arg2Arg1 = arg2._Arguments.ElementAt(0); ScriptElement Arg2Arg2 = arg2._Arguments.ElementAt(1); arg2._Arguments.Clear(); arg2._Arguments.Add(opElement); arg2._Arguments.Add(Arg2Arg2); opElement._Arguments.Clear(); opElement._Arguments.Add(Arg1Arg1); opElement._Arguments.Add(Arg2Arg1); opElement = arg2; } } ret = opElement; ret._Reorderable = true; ValidateFunction(opElement); } return ret; }
public static void ValidateFunction(ScriptElement func) { bool foundFunction = false; bool validNumParams = false; bool validTypeParams = false; foreach (DistFunc df in _DistFunc) { if (df._Name.Equals(func._String, StringComparison.Ordinal)) { foundFunction = true; if (df._DistParams.Count == func._Arguments.Count) { validNumParams = true; bool functionParamsValid = true; for (int i = 0; i < df._DistParams.Count; i++) { if (df._DistParams.ElementAt(i)._Type != func._Arguments.ElementAt(i)._Type) functionParamsValid = false; } if (functionParamsValid) { validTypeParams = true; func._Type = df._ReturnType; } } } } if (!foundFunction) throw new ParseException("Missing distance function looking up \"" + func._String + "\""); if (!validNumParams) throw new ParseException("No matching version of function \"" + func._String + "\" found expecting " + func._Arguments.Count + " parameters"); if (!validTypeParams) throw new ParseException("Type mismatch on args for function \"" + func._String + "\""); }