예제 #1
0
        /// <summary>
        /// Implements applicative-order evaluation.
        /// </summary>
        /// <param name="env"></param>
        /// <returns></returns>
        public override IValue Evaluate(Environment env)
        {
            // Eval and get the operator
            IValue procedure = ProcedureExpression.Evaluate(env);

            // Both primitive & compound procedures are strict
            var arguments = from argExpr in ArgumentExpressions
                            select argExpr.Evaluate(env);

            switch (procedure)
            {
            case PrimitiveProcedure pproc:
                return(pproc.Execute(arguments.ToList()));

            case CompoundProcedure cproc:
                return(cproc.Execute(arguments.ToList()));

            default:
                throw new RuntimeErrorException("procedure application", $"Expected a procedure that can be applied. Given: {procedure.Represent()}");
            }
        }
예제 #2
0
        static void ProcedureProcessor(StringBuilder stringBuilder, ProcedureExpression expression, ShaderMetadata metadata)
        {
            // SWAP ARGUMENTS !!!

            if (expression == null)
            {
                return;
            }

            // Pre process
            // For procedure "tex2D"
            if (expression.Name.Equals("tex2D") && metadata is PixelShaderMetadata)
            {
                // Cast to pixel metadata
                var pixelMetadata = metadata as PixelShaderMetadata;

                // Find tex2D syntax part
                TextPart tex2DPart = expression.ConstituentSymbols[0] as TextPart;

                // Find sampler name
                TextPart samplerPart = expression.ConstituentSymbols[2] as TextPart;

                // Find sampler expression
                SamplerExpression samplerExpression = pixelMetadata.Samplers.Find(s => s.Name == samplerPart.TextValue);

                if (samplerExpression == null)
                {
                    throw new ArgumentNullException("samplerExpression");
                }

                // Find texture name
                if (string.IsNullOrEmpty(samplerExpression.Resource))
                {
                    throw new ArgumentNullException("samplerExpression.Resource");
                }

                // Modify
                tex2DPart.TextValue = samplerExpression.Resource + ".Sample";
            }
            if (expression.Name.Equals("texCube") && metadata is PixelShaderMetadata)
            {
                // Cast to pixel metadata
                var pixelMetadata = metadata as PixelShaderMetadata;

                // Find tex2D syntax part
                TextPart texCubePart = expression.ConstituentSymbols[0] as TextPart;

                // Find sampler name
                TextPart samplerPart = expression.ConstituentSymbols[2] as TextPart;

                // Find sampler expression
                SamplerExpression samplerExpression = pixelMetadata.Samplers.Find(s => s.Name == samplerPart.TextValue);

                if (samplerExpression == null)
                {
                    throw new ArgumentNullException("samplerExpression");
                }

                // Find texture name
                if (string.IsNullOrEmpty(samplerExpression.Resource))
                {
                    throw new ArgumentNullException("samplerExpression.Resource");
                }

                // Modify
                texCubePart.TextValue = samplerExpression.Resource + ".Sample";
            }
            // Check for unsupport construct float4x4(n) in hlsl, so convert to (float4x4)n
            if (expression.Name.Equals("float4x4"))
            {
                // Find float4x4 syntax part
                TextPart float4x4Part = expression.ConstituentSymbols[0] as TextPart;

                // Find value name
                TextPart valuePart = expression.ConstituentSymbols[2] as TextPart;

                if (valuePart != null &&
                    (valuePart.TextValue.Equals("0") || valuePart.TextValue.Equals(".0") ||
                     valuePart.TextValue.Equals(".0f") || valuePart.TextValue.Equals("0.0") || valuePart.TextValue.Equals("0.0f")))
                {
                    // Remove procedur name and value => "()"
                    expression.ConstituentSymbols.Remove(float4x4Part);
                    expression.ConstituentSymbols.Remove(valuePart);

                    // Insert procedur name to bracket => (float4x4)
                    expression.ConstituentSymbols.Insert(1, float4x4Part);
                    // Insert value in last => (float4x4)n
                    expression.ConstituentSymbols.Add(valuePart);
                }
            }
            // For other procedure .... like clamp, max, min, etc (in HLSL is not needed, maybe do it on GLSL)

            // Main
            CommonProcessor(stringBuilder, expression.ConstituentSymbols, metadata);
        }
예제 #3
0
 /// <summary>
 /// Parses a procedure expression.
 /// </summary>
 public static void AcceptProcedure(string Text, int Start, out ProcedureExpression Expression, out int LastChar)
 {
     List<Statement> statements = new List<Statement>();
     Statement statement;
     if (AcceptStatement(Text, Start, out statement, out LastChar))
     {
         statements.Add(statement);
         while (true)
         {
             int nc;
             AcceptWhitespace(Text, LastChar, out nc);
             if (AcceptStatement(Text, nc, out statement, out nc))
             {
                 LastChar = nc;
                 statements.Add(statement);
             }
             else
             {
                 Expression = new ProcedureExpression(statements);
                 return;
             }
         }
     }
     else
     {
         LastChar = Start;
         Expression = new ProcedureExpression(new List<Statement>());
     }
 }