상속: IExpression
예제 #1
0
        private static string GetArgument(MessageExpression expression, string key)
        {
            string[] keys = expression.Selector.Split(':');

            for (int k = 0; k < keys.Length; k++)
                if (keys[k] == key)
                    return (string)((ConstantExpression)expression.Arguments.ElementAt(k)).Value;

            return null;
        }
예제 #2
0
        public override void Visit(MessageExpression expression)
        {
            int initialposition = this.block.Bytecodes == null ? 0 : this.block.Bytecodes.Length;

            expression.Target.Visit(this);

            int condposition = this.block.Bytecodes == null ? 0 : this.block.Bytecodes.Length;

            foreach (var arg in expression.Arguments)
                arg.Visit(this);

            if (expression.Selector == "whileTrue:" || expression.Selector == "whileFalse:")
            {
                this.block.CompileByteCode(ByteCode.Value);
                this.block.CompileByteCode(ByteCode.Pop);
                this.block.CompileJumpByteCode(ByteCode.Jump, (short)initialposition);
                this.block.CompileInsert(condposition, 4);
                int finalposition = this.block.Bytecodes.Length;
                this.block.CompileBlockJumpByteCodeAt(expression.Selector == "whileFalse:" ? ByteCode.JumpIfTrue : ByteCode.JumpIfFalse, (short)finalposition, condposition);
            }
            else if (expression.Selector == "ifFalse:" || expression.Selector == "ifTrue:")
            {
                this.block.CompileByteCode(ByteCode.Value);
                this.block.CompileInsert(condposition, 7);
                this.block.CompileJumpByteCodeAt(expression.Selector == "ifFalse:" ? ByteCode.JumpIfFalse : ByteCode.JumpIfTrue, (short)(condposition + 7), condposition);
                this.block.CompileByteCodeAt(ByteCode.GetNil, condposition + 3);
                int finalposition = this.block.Bytecodes.Length;
                this.block.CompileJumpByteCodeAt(ByteCode.Jump, (short)finalposition, condposition + 4);
            }
            else if (expression.IsBinaryMessage)
                this.block.CompileBinarySend(expression.Selector);
            else
                this.block.CompileSend(expression.Selector);
        }
예제 #3
0
파일: Compiler.cs 프로젝트: ajlopez/AjTalk
 public override void Visit(FluentMessageExpression expression)
 {
     this.writer.Write("(function () {");
     this.writer.Write("var _aux = ");
     
     // TODO It's not implemented yet
     expression.Target.Visit(this);
     this.writer.Write(";");
     MessageExpression msg = new MessageExpression(new VariableExpression("_aux"), expression.Target.Selector, expression.Target.Arguments);
     this.writer.Write("return _aux;})()");
 }
예제 #4
0
파일: Compiler.cs 프로젝트: ajlopez/AjTalk
        // TODO Remove (only for demo purpose)
        public void OldVisit(MessageExpression expression)
        {
            string selector = expression.Selector;
            bool nested = false;

            if (expression.Target is MessageExpression && ((MessageExpression)expression.Target).IsBinaryMessage)
                nested = true;
            else if (expression.Target is SetExpression)
                nested = true;
            else if (expression.Target is BlockExpression)
                nested = true;

            if (!char.IsLetter(selector[0]) && expression.Arguments.Count() == 1)
            {
                if (nested)
                    this.writer.Write("(");

                // TODO Refactor: repeated code below
                if (expression.Target is ConstantExpression)
                {
                    ConstantExpression cexpr = (ConstantExpression)expression.Target;

                    // TODO other types, scape characters in string
                    if (cexpr.Value is string)
                        this.writer.Write(string.Format("String({0})", cexpr.AsString()));
                    else if (cexpr.Value is int)
                        this.writer.Write(string.Format("Number({0})", cexpr.Value));
                    else if (cexpr.Value is bool)
                        this.writer.Write(string.Format("Boolean({0})", cexpr.Value));
                }
                else
                    expression.Target.Visit(this);

                if (nested)
                    this.writer.Write(")");

                if (OperatorHasMethodName(selector))
                {
                    this.writer.Write("." + OperatorToMethodName(selector) + "(");
                    expression.Arguments.First().Visit(this);
                    this.writer.Write(")");
                }
                else
                {
                    this.writer.Write(" " + OperatorToJsOperator(selector) + " ");
                    expression.Arguments.First().Visit(this);
                }

                return;
            }

            if (expression.Target is ConstantExpression)
            {
                ConstantExpression cexpr = (ConstantExpression)expression.Target;

                // TODO other types, scape characters in string
                if (cexpr.Value is string)
                    this.writer.Write(string.Format("String({0})", cexpr.AsString()));
                else if (cexpr.Value is int)
                    this.writer.Write(string.Format("Number({0})", cexpr.Value));
                else if (cexpr.Value is bool)
                    this.writer.Write(string.Format("Boolean({0})", cexpr.Value.ToString().ToLower()));
            }
            else
            {
                if (nested)
                    this.writer.Write("(");
                expression.Target.Visit(this);
                if (nested)
                    this.writer.Write(")");
            }

            this.writer.Write(string.Format(".{0}(", ToMethodName(expression.Selector)));

            int narg = 0;
            foreach (var argument in expression.Arguments)
            {
                if (narg != 0)
                    this.writer.Write(", ");
                argument.Visit(this);
                narg++;
            }

            this.writer.Write(")");
        }
예제 #5
0
파일: Compiler.cs 프로젝트: ajlopez/AjTalk
        public override void Visit(MessageExpression expression)
        {
            if (this.CurrentMethod != null && expression.Target is ILeftValue && ((ILeftValue)expression.Target).Name == "super")
            {
                this.writer.Write(string.Format("sendSuper(self, {0}", this.CurrentMethod.Class.Name));
            }
            else
            {
                this.writer.Write("send(");

                // TODO Quick hack, if Uppercase name it's assume is a class
                if (expression.Target is ILeftValue && char.IsUpper(((ILeftValue)expression.Target).Name[0]))
                    this.writer.Write(string.Format("{0}.classPrototype", ((ILeftValue)expression.Target).Name));
                else
                    expression.Target.Visit(this);
            }

            this.writer.Write(string.Format(", '{0}'", ToMethodName(expression.Selector)));

            if (expression.Arguments.Count() > 0) 
            {
                this.writer.Write(", [");
                int narg = 0;

                foreach (var argument in expression.Arguments)
                {
                    if (narg > 0)
                        this.writer.Write(", ");

                    argument.Visit(this);

                    narg++;
                }

                this.writer.Write("]");
            }

            this.writer.Write(")");
        }
예제 #6
0
        public override void Visit(MessageExpression expression)
        {
            if (this.CurrentMethod != null && expression.Target is ILeftValue && ((ILeftValue)expression.Target).Name == "super")
            {
                base.Visit(expression);
                return;
            }

            if (expression.Selector == "napply:with:")
            {
                this.WriteLineStart("(function() {");
                this.Write("var __target = ");
                expression.Target.Visit(this);
                this.WriteLine(";");
                this.Write("return __target[");
                expression.Arguments.First().Visit(this);
                this.Write("].apply(__target, ");
                expression.Arguments.Skip(1).First().Visit(this);
                this.WriteLine(");");
                this.WriteLineEnd("})()");
                return;
            }

            if (expression.Selector == "nnew")
            {
                this.WriteLineStart("(function() {");
                this.Write("var __target = ");
                expression.Target.Visit(this);
                this.WriteLine(";");
                this.WriteLine("return __target.prototype.constructor.apply(__target, null);");
                this.WriteLineEnd("})()");
                return;
            }

            if (expression.Selector == "nnew:")
            {
                this.WriteLineStart("(function() {");
                this.Write("var __target = ");
                expression.Target.Visit(this);
                this.WriteLine(";");
                this.Write("return __target.prototype.constructor.apply(__target, ");
                expression.Arguments.First().Visit(this);
                this.WriteLine(");");
                this.WriteLineEnd("})()");
                return;
            }

            expression.Target.Visit(this);

            if (expression.Selector == "nat:")
            {
                this.Write("[");
                expression.Arguments.First().Visit(this);
                this.Write("]");
                return;
            }

            if (expression.Selector == "nat:put:")
            {
                this.Write("[");
                expression.Arguments.First().Visit(this);
                this.Write("] = ");
                expression.Arguments.Skip(1).First().Visit(this);
                return;
            }

            if (expression.Selector == "napply:")
            {
                this.Write("[");
                expression.Arguments.First().Visit(this);
                this.Write("]()");
                return;
            }

            if (expression.Target is ConstantExpression || !char.IsLetter(expression.Selector[0]))
                this.Write(string.Format("['{0}'](", ToMethodName(expression.Selector)));
            else
                this.Write(string.Format(".{0}(", ToMethodName(expression.Selector)));

            int narg = 0;

            foreach (var argument in expression.Arguments)
            {
                if (narg > 0)
                    this.Write(", ");

                argument.Visit(this);

                narg++;
            }

            this.Write(")");
        }
예제 #7
0
        private static IList<string> GetNamesFromArgument(MessageExpression expression, string key)
        {
            string[]keys = expression.Selector.Split(':');

            for (int k = 0; k < keys.Length; k++)
                if (keys[k] == key)
                    return GetNames((ConstantExpression)expression.Arguments.ElementAt(k));

            return null;
        }
예제 #8
0
        private IExpression ParseHeadExpression()
        {
            Token token = this.NextToken();

            if (token == null)
                return null;

            switch (token.Type)
            {
                case TokenType.Name:
                    if (token.Value == "self")
                        return new SelfExpression();
                    if (token.Value == "true")
                        return new ConstantExpression(true);
                    if (token.Value == "false")
                        return new ConstantExpression(false);
                    if (token.Value == "nil" || token.Value == "null")
                        return new ConstantExpression(null);

                    if (this.@class != null && this.isClassMethod == false && [email protected](token.Value))
                        return new InstanceVariableExpression(token.Value);

                    if (this.@class != null && this.isClassMethod == true && [email protected](token.Value))
                        return new ClassVariableExpression(token.Value, this.@class);

                    return new VariableExpression(token.Value);

                case TokenType.DottedName:
                    string[] names = token.Value.Split('.');
                    IExpression expr = new VariableExpression(names[0]);

                    foreach (var name in names.Skip(1))
                        expr = new MessageExpression(expr, "at:", new IExpression[] { new ConstantExpression(name) });

                    return expr;

                case TokenType.String:
                    return new ConstantExpression(token.Value);

                case TokenType.Character:
                    return new ConstantExpression(token.Value[0]);

                case TokenType.Symbol:
                    return new SymbolExpression(token.Value);

                case TokenType.Operator:
                    if (token.Value == "<")
                        return this.ParsePrimitive();
                    if (token.Value == "-")
                        return new MessageExpression(this.ParseHeadExpression(), "-", null);
                    break;

                case TokenType.Punctuation:
                    if (token.Value == "[")
                    {
                        var result = this.ParseInternalBlock();
                        this.ParseToken(TokenType.Punctuation, "]");
                        return result;
                    }

                    if (token.Value == "#(")
                        return this.ParseArray();

                    if (token.Value == "#[")
                        return this.ParseByteArray();

                    if (token.Value == "{")
                        return this.ParseDynamicArray();

                    if (token.Value == "(")
                    {
                        IExpression expression = this.ParseExpression();
                        Token lasttoken = this.NextToken();

                        if (lasttoken == null || lasttoken.Type != TokenType.Punctuation || lasttoken.Value != ")")
                        {
                            this.PushToken(lasttoken);
                            return this.ParseExpression(expression);
                        }

                        return expression;
                    }

                    break;

                case TokenType.Integer:
                    long value = 0;
                    int position = token.Value.IndexOf('r');

                    if (position > 0)
                    {
                        string strradix = token.Value.Substring(0, position);
                        string strnumber = token.Value.Substring(position + 1);
                        value = Convert.ToInt64(strnumber, Convert.ToInt32(strradix));
                    }
                    else
                        value = Convert.ToInt64(token.Value);

                    if (value > int.MaxValue || value < int.MinValue)
                        return new ConstantExpression(value);
                    else
                        return new ConstantExpression((int)value);

                case TokenType.Real:
                    return new ConstantExpression(Convert.ToDouble(token.Value, CultureInfo.InvariantCulture));
            }

            this.PushToken(token);

            return null;
        }
예제 #9
0
 private static string GetCategory(MessageExpression expression)
 {
     return GetArgument(expression, "category");
 }
예제 #10
0
        private void ProcessMessageExpression(CodeModel model, MessageExpression expression)
        {
            // TODO implements weakSubclass
            if (expression.Selector.StartsWith("subclass:") || expression.Selector.StartsWith("weakSubclass:") || expression.Selector.StartsWith("variableSubclass:"))
            {
                bool isvariable = expression.Selector.StartsWith("variableSubclass:");
                SymbolExpression symbol = (SymbolExpression)expression.Arguments.First();
                VariableExpression variable = (VariableExpression)expression.Target;

                ClassModel super = null;

                if (variable.Name != null && variable.Name != symbol.Symbol)
                    //// TODO review quick hack if class is not defined yet
                    if (model.HasClass(variable.Name))
                        super = model.GetClass(variable.Name);

                ClassModel @class;

                if (super != null || variable.Name == null)
                    @class = new ClassModel(symbol.Symbol, super, GetInstanceVariableNames(expression), GetClassVariableNames(expression), isvariable, GetPoolDictionariesNames(expression), GetCategory(expression));
                else
                    @class = new ClassModel(symbol.Symbol, variable.Name, GetInstanceVariableNames(expression), GetClassVariableNames(expression), isvariable, GetPoolDictionariesNames(expression), GetCategory(expression));

                model.AddElement(@class);
            }
        }
예제 #11
0
        private void ProcessMethods(CodeModel model, MessageExpression expression)
        {
            string className = expression.Target.AsString();
            ClassModel @class = model.GetClass(className);

            for (string chunk = this.reader.GetChunk(); chunk != null; chunk = this.reader.GetChunk())
            {
                if (string.IsNullOrEmpty(chunk.Trim()))
                    break;
                ModelParser parser = new ModelParser(chunk);
                MethodModel method = parser.ParseMethod(@class, false);
                model.AddElement(method);
            }
        }
예제 #12
0
 private void ProcessComment(CodeModel model, MessageExpression expression)
 {
     this.reader.GetChunk();
 }
예제 #13
0
 private static IList<string> GetPoolDictionariesNames(MessageExpression expression)
 {
     return GetNamesFromArgument(expression, "poolDictionaries");
 }
예제 #14
0
        private IExpression ParseSimpleExpression(IExpression expression)
        {
            if (expression is ILeftValue && this.TryParseSet())
            {
                return new SetExpression((ILeftValue)expression, this.ParseExpression());
            }

            string selector = this.TryParseUnarySelector();

            while (selector != null)
            {
                expression = new MessageExpression(expression, selector, null);
                selector = this.TryParseUnarySelector();
            }

            return expression;
        }
예제 #15
0
 public FluentMessageExpression(MessageExpression target)
 {
     this.target = target;
 }
예제 #16
0
 private static IList<string> GetInstanceVariableNames(MessageExpression expression)
 {
     return GetNamesFromArgument(expression, "instanceVariableNames");
 }
예제 #17
0
 public abstract void Visit(MessageExpression expression);
예제 #18
0
        private IExpression ParseBinaryExpression(IExpression target)
        {
            IExpression expression = this.ParseSimpleExpression(target);

            if (expression == null)
                return expression;

            string selector = this.TryParseBinarySelector();

            while (selector != null)
            {
                List<IExpression> arguments = new List<IExpression>();
                arguments.Add(this.ParseSimpleExpression());
                expression = new MessageExpression(expression, selector, arguments);
                selector = this.TryParseBinarySelector();
            }

            return expression;
        }