예제 #1
0
 public BlockEvaluator(STBlock block, Compiler compiler, Context context)
 {
     Block = block;
     Compiler = compiler;
     Result = null;
     Context = context;
 }
예제 #2
0
        public STBlock(Node blockLiteral, Context context, Compiler compiler)
        {
            Compiler = compiler;
            OuterContext = context;
            Context = new LocalContext(context, true);

            BlockLiteral = blockLiteral;
            BlockArgumentNames = new string[0];
            LocalVariableNames = new string[0];

            int i = 1;

            Node blockParams = null;

            if (blockLiteral[i].Name == "block_params")
                blockParams = blockLiteral[i++];

            if (blockLiteral[i].Name == "sequence") {
                Sequence = blockLiteral[i++];

                if (Sequence[0].Name == "var_def") {
                    List<string> varNames = new List<string>();
                    var vardef = Sequence[0];
                    for (int j = 1, max = vardef.Count; j < max; ++j) {
                        if (vardef[j].Name == "VAR_DELIM") break;
                        var varName = (vardef[j] as Token).Image;
                        varNames.Add (varName);
                        Context.Declare(varName);
                    }

                    LocalVariableNames = varNames.ToArray();
                }
            }

            if (blockParams != null) {
                var parms = blockParams;
                List<string> parmNames = new List<string>();
                for (int j = 0, max = parms.Count; j < max; ++j) {
                    var child = parms[j];
                    if (child.Name == "VAR_DELIM")
                        break;
                    var parmName = (parms[++j] as Token).Image;
                    parmNames.Add (parmName);
                    Context.Declare(parmName);
                }

                BlockArgumentNames = parmNames.ToArray();
            }
        }
예제 #3
0
        public STObject GetArrayLiteral(Node literal, Context context)
        {
            List<object> items = new List<object>();
            for (int i = 1, max = literal.Count; i < max; i += 2) {
                var expr = literal[i];
                if (expr.Name != "expression") break;
                items.Add(EvaluateExpression(expr, context));
            }

            return new Irontalk.Array(items.ToArray());
        }
예제 #4
0
 public STObject EvaluateUnarySend(STObject receiver, Node unarySend, Context context)
 {
     receiver = receiver.Dereference();
     return receiver.Send(STSymbol.Get((unarySend.GetChildAt(0) as Token).Image));
 }
예제 #5
0
        public STObject EvaluateStatement(Node statement, Context context)
        {
            int exprIndex = 0;
            bool returning = false;
            Console.WriteLine (statement.Name);
            if (statement[0].Name == "RETURN") {
                returning = true;
                ++exprIndex;
            }

            if (statement[exprIndex].Name != "expression")
                return STUndefinedObject.Instance;

            var value = EvaluateExpression(statement[exprIndex], context);

            if (returning)
                throw new ReturnException(value, context);

            return value;
        }
예제 #6
0
 public STObject EvaluateSimpleSend(STObject receiver, Node simpleSend, Context context)
 {
     var child = simpleSend.GetChildAt(0);
     if (child.Name == "unary_send")
         return EvaluateUnarySend(receiver, child, context);
     else if (child.Name == "binary_send")
         return EvaluateBinarySend(receiver, child, context);
     else
         throw new NotImplementedException("Unhandled grammar production within 'simple_send'");
 }
예제 #7
0
 public STVariable(string name, Context context)
 {
     Name = name;
     Context = context;
 }
예제 #8
0
 public LocalContext(Context parent, bool explicitVariables)
     : base(parent)
 {
     ExplicitVariables = explicitVariables;
 }
예제 #9
0
        public STObject EvaluateExpression(Node expression, Context context)
        {
            STObject receiver = EvaluateReceiver (expression.GetChildAt(0), context);

            for (int i = 1, max = expression.GetChildCount(); i < max; ++i) {
                receiver = EvaluateSend(receiver, expression.GetChildAt(i), context);
            }

            receiver = receiver.Dereference();

            return receiver;
        }
예제 #10
0
        public STObject EvaluateBinarySend(STObject receiver, Node binarySend, Context context)
        {
            STObject other = EvaluateReceiver(binarySend.GetChildAt(1), context).Dereference();
            receiver = receiver.Dereference();

            for (int i = 2, max = binarySend.GetChildCount(); i < max; ++i)
                other = EvaluateUnarySend(other, binarySend.GetChildAt(i), context);
            return receiver.Send(STSymbol.Get((binarySend.GetChildAt(0) as Token).Image), other);
        }
예제 #11
0
        public STObject EvaluateAssignSend(STObject receiver, Node assignSend, Context context)
        {
            STObject other = EvaluateExpression(assignSend.GetChildAt(1), context).Dereference();

            var variable = receiver as STVariable;

            if (variable == null)
                throw new Exception ("Error: can only assign to a valid variable lvalue");

            variable.Set(other);
            return other;
        }
예제 #12
0
 public STObject Evaluate(string str, Context context)
 {
     try {
         return Evaluate (new EvalSource (str), context);
     } catch (ReturnException e) {
         return e.Value;
     }
 }
예제 #13
0
        public STObject Evaluate(InputSource source, Context context)
        {
            Source = source;
            try {
                Node root = source.Parse(Parser);

                if (root == null)
                    return STUndefinedObject.Instance; // parser found empty string so aborted

                if (STDebug.ShowParseTrees) {
                    var tr = Transcript.Instance;
                    if (tr != null)
                        root.PrintTo(tr.Out);
                    else
                        root.PrintTo(Console.Out);
                }

                return Evaluate (root, context);
            } finally {
                Source = null;
            }
        }
예제 #14
0
        public STObject Evaluate(Node sequence, Context context)
        {
            int start = 0;

            if (sequence.GetChildAt(start).Name == "var_def")
                ++start;

            STObject last = STUndefinedObject.Instance;

            for (int i = start, max = sequence.Count; i < max; ++i) {
                var node = sequence[i];
                if (node.Name == "DOT") continue;
                last = EvaluateStatement (node, context);
            }

            return last;
        }
예제 #15
0
 public ReturnException(STObject value, Context context)
     : base("The value " + value + " is being returned")
 {
     Value = value;
 }
예제 #16
0
        public STObject EvaluateKeywordSend(STObject receiver, Node keywordSend, Context context)
        {
            receiver = receiver.Dereference();
            // keyword_send		= ( KEYWORD receiver simple_send* )+;
            string keyword = null;
            STObject parm = null;
            StringBuilder selectorBuffer = new StringBuilder();
            List<STObject> parms = new List<STObject>();

            for (int i = 0, max = keywordSend.GetChildCount(); i < max; ++i) {
                var item = keywordSend.GetChildAt(i);
                if (item.Name == "KEYWORD") {
                    if (keyword != null) {
                        selectorBuffer.Append(keyword);
                        parms.Add (parm);
                    }

                    keyword = (item as Token).Image;
                    parm = EvaluateReceiver(keywordSend.GetChildAt(++i), context).Dereference();
                } else if (item.Name == "simple_send") {
                    parm = EvaluateSimpleSend(parm, item, context);
                }
            }

            selectorBuffer.Append(keyword);
            parms.Add (parm);
            STSymbol selector = STSymbol.Get(selectorBuffer.ToString());

            return receiver.Send(selector, parms.ToArray());
        }
예제 #17
0
        public STObject EvaluateReceiver(Node receiver, Context context)
        {
            Node child = receiver.GetChildAt(0);
            if (child.Name == "IDENT") {
                return new STVariable((receiver[0] as Token).Image, context);
                //return context.GetVariable((receiver.GetChildAt(0) as Token).Image);
            } else if (child.Name == "NUM") {
                return GetNumberLiteral(child as Token);
            } else if (child.Name == "CHAR") {
                return GetCharLiteral(child as Token);
            } else if (child.Name == "symbol") {
                return GetSymbolLiteral(child);
            } else if (child.Name == "STRING") {
                return GetStringLiteral(child as Token);
            } else if (child.Name == "word_array") {
                return GetWordArrayLiteral(child);
            } else if (child.Name == "LEFT_PAREN") {
                return EvaluateExpression(receiver.GetChildAt(1), context);
            } else if (child.Name == "block") {
                return new STBlock (child, context, this);
            } else if (child.Name == "array") {
                return GetArrayLiteral(child, context);
            }

            return STUndefinedObject.Instance;
        }
예제 #18
0
 public LocalContext(Context parent)
     : this(parent, false)
 {
 }
예제 #19
0
        public STObject EvaluateSend(STObject receiver, Node message, Context context)
        {
            Node child = message.GetChildAt(0);

            if (child.Name == "simple_send")
                return EvaluateSimpleSend(receiver, child, context);
            else if (child.Name == "keyword_send")
                return EvaluateKeywordSend(receiver, child, context);
            else if (child.Name == "assign_send")
                return EvaluateAssignSend(receiver, child, context);
            throw new Exception("Should not reach");
        }
예제 #20
0
        public STObject EvaluateWith(Context context)
        {
            if (BlockArgumentNames.Length != 0)
                throw new Exception("Incorrect number of arguments for block (expected " + BlockArgumentNames.Length + ")");

            if (Compiled != null)
                throw new NotImplementedException();

            var eval = new BlockEvaluator (this, Compiler, context);
            Visit (eval);
            return eval.Result;
        }
예제 #21
0
 public Context(Context pc)
 {
     ParentContext = pc;
 }