示例#1
0
        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);
        }
示例#2
0
        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 + "\"");
            }
        }
示例#3
0
        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);
        }
示例#4
0
        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);
        }
示例#5
0
        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;
        }
示例#6
0
 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 + "\"");
 }