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; }
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); }
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;})()"); }
// 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(")"); }
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(")"); }
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(")"); }
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; }
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; }
private static string GetCategory(MessageExpression expression) { return GetArgument(expression, "category"); }
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); } }
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); } }
private void ProcessComment(CodeModel model, MessageExpression expression) { this.reader.GetChunk(); }
private static IList<string> GetPoolDictionariesNames(MessageExpression expression) { return GetNamesFromArgument(expression, "poolDictionaries"); }
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; }
public FluentMessageExpression(MessageExpression target) { this.target = target; }
private static IList<string> GetInstanceVariableNames(MessageExpression expression) { return GetNamesFromArgument(expression, "instanceVariableNames"); }
public abstract void Visit(MessageExpression expression);
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; }