public static Message Wrap(string name, object cachedResult, Runtime runtime) { Message m = new Message(runtime, name); m.cached = cachedResult; return m; }
public static IokeObject NewFromStream(Runtime runtime, TextReader reader, IokeObject message, IokeObject context) { try { iokeParser parser = new iokeParser(new CommonTokenStream(new iokeLexer(new ANTLRReaderStream(reader)))); // Console.Error.WriteLine("parseFully ..."); ITree t = parser.parseFully(); // Console.Error.WriteLine("t: " + t.ToStringTree()); if(t == null) { Message mx = new Message(runtime, ".", null, Type.TERMINATOR); mx.Line = 0; mx.Position = 0; return runtime.CreateMessage(mx); } IokeObject m = FromTree(runtime, t); // Console.Error.WriteLine("m: " + m); // Console.Error.WriteLine("m1: " + m); OpShuffle(m); // Console.Error.WriteLine("m2: " + m); return m; } catch(Exception e) { runtime.ReportNativeException(e, message, context); return null; } }
public static IokeObject NewFromStream(Runtime runtime, TextReader reader, IokeObject message, IokeObject context) { try { IokeParser parser = new IokeParser(runtime, reader, context, message); IokeObject m = parser.ParseFully(); if(m == null) { Message mx = new Message(runtime, ".", null, true); mx.Line = 0; mx.Position = 0; return runtime.CreateMessage(mx); } return m; } catch(ControlFlow cf) { // Pass through! throw cf; } catch(Exception e) { runtime.ReportNativeException(e, message, context); return null; } }
public IokeObject NewMessageFrom(IokeObject m, string name, IList args) { Message mess = new Message(this, name); mess.File = m.File; mess.Line = m.Line; mess.Position = m.Position; mess.SetArguments(args); return CreateMessage(mess); }
public static IokeObject FromTree(Runtime runtime, ITree tree) { // Console.Error.WriteLine(" fromTree(" + tree.ToStringTree() + ")"); Message m = null; int argStart = 0; if(!tree.IsNil) { switch(tree.Type) { case iokeParser.RegexpLiteral: { string s = tree.Text; char first = s[0]; char second = s[1]; char last = s[s.Length-1]; if(first == '#' && last != '{') { if(second == 'r') { int lastIndex = s.LastIndexOf(']'); m = new Message(runtime, "internal:createRegexp", s.Substring(3, lastIndex-3)); m.arguments.Add(s.Substring(lastIndex+1)); } else { int lastIndex = s.LastIndexOf('/'); m = new Message(runtime, "internal:createRegexp", s.Substring(2, lastIndex-2)); m.arguments.Add(s.Substring(lastIndex+1)); } m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); } else if(first == '}' && last == '{') { m = new Message(runtime, "internal:createText", s.Substring(1, s.Length-3), Type.MIDDLE_RE_INTERPOLATION); m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); } else if(first == '}') { int lastIndex = s.LastIndexOf('/'); if(lastIndex == -1) { lastIndex = s.LastIndexOf(']'); } m = new Message(runtime, "internal:createText", s.Substring(1, lastIndex-1), Type.END_RE_INTERPOLATION); m.arguments.Add(s.Substring(lastIndex+1)); m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); } else { m = new Message(runtime, "internal:createText", s.Substring(2, s.Length-4), Type.START_RE_INTERPOLATION); m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); } } case iokeParser.StringLiteral: { string s = tree.Text; char first = s[0]; char last = s[s.Length-1]; if(first == '"' && last == '"') { m = new Message(runtime, "internal:createText", s.Substring(1, s.Length-2)); m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); } else if(first == '#' && last == ']') { m = new Message(runtime, "internal:createText", s.Substring(2, s.Length-3)); m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); } else { if(first == '}' && (last == '"' || last == ']')) { // This is an ending m = new Message(runtime, "internal:createText", s.Substring(1, s.Length-2), Type.END_INTERPOLATION); m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); } else if(first == '"') { // This is a beginning m = new Message(runtime, "internal:createText", s.Substring(1, s.Length-3), Type.START_INTERPOLATION); m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); } else if(first == '#') { // This is a beginning m = new Message(runtime, "internal:createText", s.Substring(2, s.Length-4), Type.START_INTERPOLATION); m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); } else { // This is in the middle m = new Message(runtime, "internal:createText", s.Substring(1, s.Length-3), Type.MIDDLE_INTERPOLATION); m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); } } } case iokeParser.NumberLiteral: m = new Message(runtime, "internal:createNumber", tree.Text); m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); case iokeParser.DecimalLiteral: m = new Message(runtime, "internal:createDecimal", tree.Text); m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); case iokeParser.UnitLiteral: { string text = tree.Text; int ending = text.Length-1; while(!Char.IsDigit(text[ending])) { ending--; } Message mex = new Message(runtime, "internal:createNumber", text.Substring(0, ending+1)); mex.Line = tree.Line; mex.Position = tree.CharPositionInLine; m = new Message(runtime, "internal:createUnit", runtime.CreateMessage(mex)); m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); } case iokeParser.UnitDecimalLiteral: { string text = tree.Text; int ending = text.Length-1; while(!Char.IsDigit(text[ending])) { ending--; } Message mex = new Message(runtime, "internal:createDecimal", text.Substring(0, ending+1)); mex.Line = tree.Line; mex.Position = tree.CharPositionInLine; m = new Message(runtime, "internal:createUnit", mex); m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); } case iokeParser.Identifier: m = new Message(runtime, tree.Text); m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); case iokeParser.Terminator: m = new Message(runtime, ".", null, Type.TERMINATOR); m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); case iokeParser.Comma: m = new Message(runtime, ",", null, Type.SEPARATOR); m.Line = tree.Line; m.Position = tree.CharPositionInLine; return runtime.CreateMessage(m); case iokeParser.MESSAGE: { string text = tree.GetChild(0).Text; m = new Message(runtime, text); int count = tree.ChildCount; argStart = 1; if(count > 1) { int diff = tree.GetChild(1).CharPositionInLine - (tree.CharPositionInLine+text.Length); if(diff != 0) { m.type = Type.DETACH; } argStart = 2; } break; } default: Console.Error.WriteLine("ERROR: Can't handle " + tree + " : " + tree.Type); return null; } m.Line = tree.Line; m.Position = tree.CharPositionInLine; } IokeObject mx = m == null ? (IokeObject)null : runtime.CreateMessage(m); object head = null; IList<IokeObject> currents = new SaneList<IokeObject>(); IList<IList<IokeObject>> oldCurrents = new SaneList<IList<IokeObject>>(); IList<object> oldHeads = new SaneList<object>(); IList<IokeObject> oldMx = new SaneList<IokeObject>(); for(int i=argStart,j=tree.ChildCount; i<j; i++) { IokeObject created = FromTree(runtime, tree.GetChild(i)); switch(Message.typeOf(created)) { case Type.START_INTERPOLATION:{ Message mvv = new Message(runtime, "internal:concatenateText"); mvv.Line = tree.Line; mvv.Position = tree.CharPositionInLine; oldCurrents.Insert(0, currents); oldHeads.Insert(0, head); oldMx.Insert(0, mx); currents = new SaneList<IokeObject>(); head = created; mx = runtime.CreateMessage(mvv); created = runtime.CreateMessage(new Message(runtime, ",", null, Type.SEPARATOR)); break; } case Type.START_RE_INTERPOLATION:{ Message mvv = new Message(runtime, "internal:compositeRegexp"); mvv.Line = tree.Line; mvv.Position = tree.CharPositionInLine; oldCurrents.Insert(0, currents); oldHeads.Insert(0, head); oldMx.Insert(0, mx); currents = new SaneList<IokeObject>(); head = created.Arguments[0]; mx = runtime.CreateMessage(mvv); created = runtime.CreateMessage(new Message(runtime, ",", null, Type.SEPARATOR)); break; } case Type.MIDDLE_INTERPOLATION: mx.Arguments.Add(head); currents.Clear(); head = created; created = runtime.CreateMessage(new Message(runtime, ",", null, Type.SEPARATOR)); break; case Type.MIDDLE_RE_INTERPOLATION: mx.Arguments.Add(head); currents.Clear(); head = created.Arguments[0]; created = runtime.CreateMessage(new Message(runtime, ",", null, Type.SEPARATOR)); break; case Type.END_INTERPOLATION: mx.Arguments.Add(head); mx.Arguments.Add(created); currents = oldCurrents[0]; oldCurrents.RemoveAt(0); head = oldHeads[0]; oldHeads.RemoveAt(0); created = mx; mx = oldMx[0]; oldMx.RemoveAt(0); break; case Type.END_RE_INTERPOLATION: mx.Arguments.Add(head); mx.Arguments.Add(created.Arguments[0]); mx.Arguments.Add(created.Arguments[1]); currents = oldCurrents[0]; oldCurrents.RemoveAt(0); head = oldHeads[0]; oldHeads.RemoveAt(0); created = mx; mx = oldMx[0]; oldMx.RemoveAt(0); break; } if(Message.typeOf(created) == Type.TERMINATOR && head == null && currents.Count == 0) { continue; } if(Message.typeOf(created) == Type.SEPARATOR && mx != null) { mx.Arguments.Add(head); currents.Clear(); head = null; } else { if(Message.typeOf(created) == Type.TERMINATOR && currents.Count > 1) { while(currents.Count > 1) { currents.RemoveAt(0); } } Message.SetPrev(created, currents.Count > 0 ? currents[0] : null); if(head == null && Message.typeOf(created) != Type.TERMINATOR) { head = created; } if(currents.Count > 0) { Message.SetNextOfLast(currents[0], created); currents[0] = created; } else { currents.Insert(0, created); } } } if(mx != null && head != null) { mx.Arguments.Add(head); } return mx == null ? (IokeObject)head : mx; }
private IokeObject parseText(int indicator) { StringBuilder sb = new StringBuilder(); bool dquote = indicator == '"'; int l = lineNumber; int cc = currentCharacter-1; if(!dquote) { read(); } int rr; string name = "internal:createText"; ArrayList args = new SaneArrayList(); while(true) { switch(rr = peek()) { case -1: fail("Expected end of text, found EOF"); break; case '"': read(); if(dquote) { args.Add(sb.ToString()); Message m = new Message(runtime, "internal:createText"); m.Line = l; m.Position = cc; IokeObject mm = runtime.CreateMessage(m); if(!name.Equals("internal:createText")) { for(int i = 0; i<args.Count; i++) { object o = args[i]; if(o is string) { Message mx = new Message(runtime, "internal:createText", o); mx.Line = l; mx.Position = cc; IokeObject mmx = runtime.CreateMessage(mx); args[i] = mmx; } } Message.SetName(mm, name); } Message.SetArguments(mm, args); return mm; } else { sb.Append((char)rr); } break; case ']': read(); if(!dquote) { args.Add(sb.ToString()); Message m = new Message(runtime, "internal:createText"); m.Line = l; m.Position = cc; IokeObject mm = runtime.CreateMessage(m); if(!name.Equals("internal:createText")) { for(int i = 0; i<args.Count; i++) { object o = args[i]; if(o is string) { Message mx = new Message(runtime, "internal:createText", o); mx.Line = l; mx.Position = cc; IokeObject mmx = runtime.CreateMessage(mx); args[i] = mmx; } } Message.SetName(mm, name); } Message.SetArguments(mm, args); return mm; } else { sb.Append((char)rr); } break; case '#': read(); if((rr = peek()) == '{') { read(); args.Add(sb.ToString()); sb = new StringBuilder(); name = "internal:concatenateText"; args.Add(parseExpressions()); readWhiteSpace(); parseCharacter('}'); } else { sb.Append((char)'#'); } break; case '\\': read(); parseDoubleQuoteEscape(sb); break; default: read(); sb.Append((char)rr); break; } } }
public IokeObject CreateMessage(Message m) { IokeObject obj = this.Message.AllocateCopy(null, null); obj.MimicsWithoutCheck(this.Message); obj.Data = m; return obj; }
private IokeObject parseSquareMessageSend() { int l = lineNumber; int cc = currentCharacter-1; int rr = peek(); int r2 = peek2(); Message m = new Message(runtime, "[]"); m.Line = l; m.Position = cc; IokeObject mx = runtime.CreateMessage(m); if(rr == ']' && r2 == '(') { read(); read(); IList args = parseExpressionChain(); parseCharacter(')'); Message.SetArguments(mx, args); } else { IList args = parseExpressionChain(); parseCharacter(']'); Message.SetArguments(mx, args); } return mx; }
public static void Init(IokeObject obj) { Runtime runtime = obj.runtime; obj.Kind = "DefaultBehavior Literals"; obj.RegisterMethod(runtime.NewNativeMethod("Takes one evaluated argument that is expected to be a Text, and returns the symbol corresponding to that text", new NativeMethod(":", DefaultArgumentsDefinition.builder() .WithRequiredPositional("symbolText") .Arguments, (method, context, message, on, outer) => { var args = new SaneArrayList(); outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary<string, object>()); string sym = Text.GetText(Interpreter.Send(runtime.asText, context, args[0])); return runtime.GetSymbol(sym); }))); obj.RegisterMethod(runtime.NewNativeMethod("Takes one evaluated argument and returns a new Pair of the receiver and the argument", new NativeMethod("=>", DefaultArgumentsDefinition.builder() .WithRequiredPositional("other") .Arguments, (method, context, message, on, outer) => { var args = new SaneArrayList(); outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary<string, object>()); return context.runtime.NewPair(on, args[0]); }))); obj.RegisterMethod(runtime.NewNativeMethod("returns a new message with the name given as argument to this method.", new NativeMethod("message", DefaultArgumentsDefinition.builder() .WithRequiredPositional("name") .Arguments, (method, context, message, on, outer) => { var args = new SaneArrayList(); outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary<string, object>()); object o = args[0]; string name = null; if(IokeObject.dataOf(o) is Text) { name = Text.GetText(o); } else { name = Text.GetText(Interpreter.Send(context.runtime.asText, context, o)); } Message m = new Message(context.runtime, name); IokeObject ret = context.runtime.CreateMessage(m); if(".".Equals(name)) { Message.SetIsTerminator(ret, true); } Message.CopySourceLocation(message, ret); return ret; }))); obj.RegisterMethod(runtime.NewNativeMethod("creates a new Set from the result of evaluating all arguments provided.", new NativeMethod("set", DefaultArgumentsDefinition.builder() .WithRest("elements") .Arguments, (method, context, message, on, outer) => { var args = new SaneArrayList(); outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary<string, object>()); return context.runtime.NewSet(args); }))); obj.RegisterMethod(runtime.NewNativeMethod("creates a new Dict from the arguments provided. these arguments can be two different things - either a keyword argument, or a pair. if it's a keyword argument, the entry added to the dict for it will be a symbol with the name from the keyword, without the ending colon. if it's not a keyword, it is expected to be an evaluated pair, where the first part of the pair is the key, and the second part is the value.", new NativeMethod("dict", DefaultArgumentsDefinition.builder() .WithRest("pairs") .WithKeywordRest("keywordPairs") .Arguments, (method, context, message, on, outer) => { outer.ArgumentsDefinition.CheckArgumentCount(context, message, on); var arguments = message.Arguments; var moo = new SaneHashtable(arguments.Count); foreach(object o in arguments) { object key, value; if(Message.IsKeyword(o)) { string str = Message.GetName(o); key = context.runtime.GetSymbol(str.Substring(0, str.Length-1)); if(Message.GetNext(o) != null) { value = Interpreter.GetEvaluatedArgument(Message.GetNext(o), context); } else { value = context.runtime.nil; } } else { object result = Interpreter.GetEvaluatedArgument(o, context); if((result is IokeObject) && (IokeObject.dataOf(result) is Pair)) { key = Pair.GetFirst(result); value = Pair.GetSecond(result); } else { key = result; value = context.runtime.nil; } } moo[key] = value; } return context.runtime.NewDict(moo); }))); }
private IokeObject parseRegularMessageSend(int indicator) { int l = lineNumber; int cc = currentCharacter-1; StringBuilder sb = new StringBuilder(); sb.Append((char)indicator); int rr = -1; while(isLetter(rr = peek()) || isIDDigit(rr) || rr == ':' || rr == '!' || rr == '?' || rr == '$') { read(); sb.Append((char)rr); } Message m = new Message(runtime, sb.ToString()); m.Line = l; m.Position = cc; IokeObject mx = runtime.CreateMessage(m); if(rr == '(') { read(); IList args = parseExpressionChain(); parseCharacter(')'); Message.SetArguments(mx, args); } return mx; }
private IokeObject parseSetMessageSend() { int l = lineNumber; int cc = currentCharacter-1; parseCharacter('{'); IList args = parseExpressionChain(); parseCharacter('}'); Message m = new Message(runtime, "set"); m.Line = l; m.Position = cc; IokeObject mx = runtime.CreateMessage(m); Message.SetArguments(mx, args); return mx; }
private IokeObject parseRegexpLiteral(int indicator) { StringBuilder sb = new StringBuilder(); bool slash = indicator == '/'; int l = lineNumber; int cc = currentCharacter-1; read(); if(!slash) { parseCharacter('['); } int rr; string name = "internal:createRegexp"; ArrayList args = new SaneArrayList(); while(true) { switch(rr = peek()) { case -1: fail("Expected end of regular expression, found EOF"); break; case '/': read(); if(slash) { args.Add(sb.ToString()); Message m = new Message(runtime, "internal:createRegexp"); m.Line = l; m.Position = cc; IokeObject mm = runtime.CreateMessage(m); if(!name.Equals("internal:createRegexp")) { Message.SetName(mm, name); } Message.SetArguments(mm, args); sb = new StringBuilder(); while(true) { switch(rr = peek()) { case 'x': case 'i': case 'u': case 'm': case 's': read(); sb.Append((char)rr); break; default: args.Add(sb.ToString()); return mm; } } } else { sb.Append((char)rr); } break; case ']': read(); if(!slash) { args.Add(sb.ToString()); Message m = new Message(runtime, "internal:createRegexp"); m.Line = l; m.Position = cc; IokeObject mm = runtime.CreateMessage(m); if(!name.Equals("internal:createRegexp")) { Message.SetName(mm, name); } Message.SetArguments(mm, args); sb = new StringBuilder(); while(true) { switch(rr = peek()) { case 'x': case 'i': case 'u': case 'm': case 's': read(); sb.Append((char)rr); break; default: args.Add(sb.ToString()); //System.err.println("-parseRegexpLiteral()"); return mm; } } } else { sb.Append((char)rr); } break; case '#': read(); if((rr = peek()) == '{') { read(); args.Add(sb.ToString()); sb = new StringBuilder(); name = "internal:compositeRegexp"; args.Add(parseExpressions()); readWhiteSpace(); parseCharacter('}'); } else { sb.Append((char)'#'); } break; case '\\': read(); parseRegexpEscape(sb); break; default: read(); sb.Append((char)rr); break; } } }
private IokeObject parseRange() { int l = lineNumber; int cc = currentCharacter-1; int count = 2; read(); while(peek() == '.') { count++; read(); } string result = null; if(count < 13) { result = RANGES[count]; } else { StringBuilder sb = new StringBuilder(); for(int i = 0; i<count; i++) { sb.Append('.'); } result = sb.ToString(); } Message m = new Message(runtime, result); m.Line = l; m.Position = cc; return runtime.CreateMessage(m); }
private IokeObject parseOperatorChars(int indicator) { int l = lineNumber; int cc = currentCharacter-1; StringBuilder sb = new StringBuilder(); sb.Append((char)indicator); int rr; if(indicator == '#') { while(true) { rr = peek(); switch(rr) { case '+': case '-': case '*': case '%': case '<': case '>': case '!': case '?': case '~': case '&': case '|': case '^': case '$': case '=': case '@': case '\'': case '`': case ':': case '#': read(); sb.Append((char)rr); break; default: Message m = new Message(runtime, sb.ToString()); m.Line = l; m.Position = cc; IokeObject mx = runtime.CreateMessage(m); if(rr == '(') { read(); IList args = parseExpressionChain(); parseCharacter(')'); Message.SetArguments(mx, args); } return mx; } } } else { while(true) { rr = peek(); switch(rr) { case '+': case '-': case '*': case '%': case '<': case '>': case '!': case '?': case '~': case '&': case '|': case '^': case '$': case '=': case '@': case '\'': case '`': case '/': case ':': case '#': read(); sb.Append((char)rr); break; default: Message m = new Message(runtime, sb.ToString()); m.Line = l; m.Position = cc; IokeObject mx = runtime.CreateMessage(m); if(rr == '(') { read(); IList args = parseExpressionChain(); parseCharacter(')'); Message.SetArguments(mx, args); } return mx; } } } }
public override IokeData CloneData(IokeObject obj, IokeObject message, IokeObject context) { Message m = new Message(obj.runtime, name); m.arguments = new SaneArrayList(((Message)IokeObject.dataOf(obj)).arguments); m.isTerminator = ((Message)IokeObject.dataOf(obj)).isTerminator; m.file = ((Message)IokeObject.dataOf(obj)).file; m.line = ((Message)IokeObject.dataOf(obj)).line; m.pos = ((Message)IokeObject.dataOf(obj)).pos; return m; }
public static void Init(IokeObject obj) { Runtime runtime = obj.runtime; obj.Kind = "DefaultBehavior Definitions"; obj.RegisterMethod(runtime.NewNativeMethod("expects any number of unevaluated arguments. if no arguments at all are given, will just return nil. creates a new method based on the arguments. this method will be evaluated using the context of the object it's called on, and thus the definition can not refer to the outside scope where the method is defined. (there are other ways of achieving this). all arguments except the last one is expected to be names of arguments that will be used in the method. there will possible be additions to the format of arguments later on - including named parameters and optional arguments. the actual code is the last argument given.", new NativeMethod("method", DefaultArgumentsDefinition.builder() .WithOptionalPositionalUnevaluated("documentation") .WithRestUnevaluated("argumentsAndBody") .Arguments, (method, context, message, on, outer) => { outer.ArgumentsDefinition.CheckArgumentCount(context, message, on); var args = message.Arguments; if(args.Count == 0) { Message mx = new Message(context.runtime, "nil", null, Message.Type.MESSAGE); mx.File = Message.GetFile(message); mx.Line = Message.GetLine(message); mx.Position = Message.GetPosition(message); IokeObject mmx = context.runtime.CreateMessage(mx); return runtime.NewMethod(null, runtime.DefaultMethod, new DefaultMethod(context, DefaultArgumentsDefinition.Empty(), mmx)); } string doc = null; int start = 0; if(args.Count > 1 && ((IokeObject)Message.GetArguments(message)[0]).Name.Equals("internal:createText")) { start++; string s = (string)((IokeObject)args[0]).Arguments[0]; doc = s; } DefaultArgumentsDefinition def = DefaultArgumentsDefinition.CreateFrom(args, start, args.Count-1, message, on, context); return runtime.NewMethod(doc, runtime.DefaultMethod, new DefaultMethod(context, def, (IokeObject)args[args.Count-1])); }))); obj.RegisterMethod(runtime.NewNativeMethod("expects one code argument, optionally preceeded by a documentation string. will create a new DefaultMacro based on the code and return it.", new NativeMethod("macro", DefaultArgumentsDefinition.builder() .WithOptionalPositionalUnevaluated("documentation") .WithOptionalPositionalUnevaluated("body") .Arguments, (method, context, message, on, outer) => { outer.ArgumentsDefinition.CheckArgumentCount(context, message, on); var args = message.Arguments; if(args.Count == 0) { Message mx = new Message(context.runtime, "nil", null, Message.Type.MESSAGE); mx.File = Message.GetFile(message); mx.Line = Message.GetLine(message); mx.Position = Message.GetPosition(message); IokeObject mmx = context.runtime.CreateMessage(mx); return runtime.NewMacro(null, runtime.DefaultMacro, new DefaultMacro(context, mmx)); } string doc = null; int start = 0; if(args.Count > 1 && ((IokeObject)Message.GetArguments(message)[0]).Name.Equals("internal:createText")) { start++; string s = (string)(((IokeObject)args[0]).Arguments[0]); doc = s; } return runtime.NewMacro(doc, runtime.DefaultMacro, new DefaultMacro(context, (IokeObject)args[start])); }))); obj.RegisterMethod(runtime.NewNativeMethod("creates a new lexical block that can be executed at will, while retaining a reference to the lexical closure it was created in. it will always update variables if they exist. there is currently no way of introducing shadowing variables in the local context. new variables can be created though, just like in a method. a lexical block mimics LexicalBlock, and can take arguments. at the moment these are restricted to required arguments, but support for the same argument types as DefaultMethod will come.", new NativeMethod("fn", DefaultArgumentsDefinition.builder() .WithOptionalPositionalUnevaluated("documentation") .WithRestUnevaluated("argumentsAndBody") .Arguments, (method, context, message, on, outer) => { outer.ArgumentsDefinition.CheckArgumentCount(context, message, on); var args = message.Arguments; if(args.Count == 0) { return runtime.NewLexicalBlock(null, runtime.LexicalBlock, new LexicalBlock(context, DefaultArgumentsDefinition.Empty(), method.runtime.nilMessage)); } string doc = null; int start = 0; if(args.Count > 1 && ((IokeObject)Message.GetArguments(message)[0]).Name.Equals("internal:createText")) { start++; string s = ((string)((IokeObject)args[0]).Arguments[0]); doc = s; } IokeObject code = IokeObject.As(args[args.Count-1], context); DefaultArgumentsDefinition def = DefaultArgumentsDefinition.CreateFrom(args, start, args.Count-1, message, on, context); return runtime.NewLexicalBlock(doc, runtime.LexicalBlock, new LexicalBlock(context, def, code)); }))); obj.RegisterMethod(runtime.NewNativeMethod("creates a new lexical block that can be executed at will, while retaining a reference to the lexical closure it was created in. it will always update variables if they exist. there is currently no way of introducing shadowing variables in the local context. new variables can be created though, just like in a method. a lexical block mimics LexicalBlock, and can take arguments. at the moment these are restricted to required arguments, but support for the same argument types as DefaultMethod will come. same as fn()", new NativeMethod("\u028E", DefaultArgumentsDefinition.builder() .WithOptionalPositionalUnevaluated("documentation") .WithRestUnevaluated("argumentsAndBody") .Arguments, (method, context, message, on, outer) => { outer.ArgumentsDefinition.CheckArgumentCount(context, message, on); var args = message.Arguments; if(args.Count == 0) { return runtime.NewLexicalBlock(null, runtime.LexicalBlock, new LexicalBlock(context, DefaultArgumentsDefinition.Empty(), method.runtime.nilMessage)); } string doc = null; int start = 0; if(args.Count > 1 && ((IokeObject)Message.GetArguments(message)[0]).Name.Equals("internal:createText")) { start++; string s = ((string)((IokeObject)args[0]).Arguments[0]); doc = s; } IokeObject code = IokeObject.As(args[args.Count-1], context); DefaultArgumentsDefinition def = DefaultArgumentsDefinition.CreateFrom(args, start, args.Count-1, message, on, context); return runtime.NewLexicalBlock(doc, runtime.LexicalBlock, new LexicalBlock(context, def, code)); }))); obj.RegisterMethod(runtime.NewNativeMethod("expects one code argument, optionally preceeded by a documentation string. will create a new LexicalMacro based on the code and return it.", new NativeMethod("lecro", DefaultArgumentsDefinition.builder() .WithOptionalPositionalUnevaluated("documentation") .WithOptionalPositionalUnevaluated("body") .Arguments, (method, context, message, on, outer) => { outer.ArgumentsDefinition.CheckArgumentCount(context, message, on); var args = message.Arguments; if(args.Count == 0) { Message mx = new Message(context.runtime, "nil", null, Message.Type.MESSAGE); mx.File = Message.GetFile(message); mx.Line = Message.GetLine(message); mx.Position = Message.GetPosition(message); IokeObject mmx = context.runtime.CreateMessage(mx); return runtime.NewMacro(null, runtime.LexicalMacro, new LexicalMacro(context, mmx)); } string doc = null; int start = 0; if(args.Count > 1 && ((IokeObject)Message.GetArguments(message)[0]).Name.Equals("internal:createText")) { start++; string s = ((string)((IokeObject)args[0]).Arguments[0]); doc = s; } return runtime.NewMacro(doc, runtime.LexicalMacro, new LexicalMacro(context, (IokeObject)args[start])); }))); obj.RegisterMethod(runtime.NewNativeMethod("expects one code argument, optionally preceeded by a documentation string. will create a new DefaultSyntax based on the code and return it.", new NativeMethod("syntax", DefaultArgumentsDefinition.builder() .WithOptionalPositionalUnevaluated("documentation") .WithOptionalPositionalUnevaluated("body") .Arguments, (method, context, message, on, outer) => { outer.ArgumentsDefinition.CheckArgumentCount(context, message, on); var args = message.Arguments; if(args.Count == 0) { Message mx = new Message(context.runtime, "nil", null, Message.Type.MESSAGE); mx.File = Message.GetFile(message); mx.Line = Message.GetLine(message); mx.Position = Message.GetPosition(message); IokeObject mmx = context.runtime.CreateMessage(mx); return runtime.NewMacro(null, runtime.DefaultSyntax, new DefaultSyntax(context, mmx)); } string doc = null; int start = 0; if(args.Count > 1 && ((IokeObject)Message.GetArguments(message)[0]).Name.Equals("internal:createText")) { start++; string s = (string)((IokeObject)args[0]).Arguments[0]; doc = s; } return runtime.NewMacro(doc, runtime.DefaultSyntax, new DefaultSyntax(context, (IokeObject)args[start])); }))); obj.RegisterMethod(runtime.NewNativeMethod("Takes two evaluated text or symbol arguments that name the method to alias, and the new name to give it. returns the receiver.", new NativeMethod("aliasMethod", DefaultArgumentsDefinition.builder() .WithRequiredPositional("oldName") .WithRequiredPositional("newName") .Arguments, (method, context, message, on, outer) => { var args = new SaneArrayList(); outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary<string, object>()); string fromName = Text.GetText(((Message)IokeObject.dataOf(runtime.asText)).SendTo(runtime.asText, context, args[0])); string toName = Text.GetText(((Message)IokeObject.dataOf(runtime.asText)).SendTo(runtime.asText, context, args[1])); IokeObject.As(on, context).AliasMethod(fromName, toName, message, context); return on; }))); }
public static void Main(string[] args) { string current = System.Reflection.Assembly.GetExecutingAssembly().Location; string iokeHome = new FileInfo(current).Directory.Parent.FullName; string iokeLib = Path.Combine(iokeHome, "lib"); Runtime r = new Runtime(new FunctionalOperatorShufflerFactory()); r.Init(); IokeObject context = r.Ground; Message mx = new Message(r, ".", null, true); mx.Line = 0; mx.Position = 0; IokeObject message = r.CreateMessage(mx); string cwd = null; var scripts = new SaneList<string>(); var loadDirs = new SaneList<string>(); bool debug = false; try { int start = 0; bool done = false; bool readStdin = false; bool printedSomething = false; for(;!done && start<args.Length;start++) { string arg = args[start]; if(arg.Length > 0) { if(arg[0] != '-') { done = true; break; } else { if(arg.Equals("--")) { done = true; } else if(arg.Equals("-d")) { debug = true; r.Debug = true; } else if(arg.StartsWith("-e")) { if(arg.Length == 2) { scripts.Add(args[++start]); } else { scripts.Add(arg.Substring(2)); } } else if(arg.StartsWith("-I")) { if(arg.Length == 2) { loadDirs.Add(args[++start]); } else { loadDirs.Add(arg.Substring(2)); } } else if(arg.Equals("-h") || arg.Equals("--help")) { Console.Error.Write(HELP); return; } else if(arg.Equals("--version")) { Console.Error.WriteLine(getVersion()); printedSomething = true; } else if(arg.Equals("--copyright")) { Console.Error.Write(COPYRIGHT); printedSomething = true; } else if(arg.Equals("-")) { readStdin = true; } else if(arg[1] == 'C') { if(arg.Length == 2) { cwd = args[++start]; } else { cwd = arg.Substring(2); } } else { IokeObject condition = IokeObject.As(IokeObject.GetCellChain(r.Condition, message, context, "Error", "CommandLine", "DontUnderstandOption"), null).Mimic(message, context); condition.SetCell("message", message); condition.SetCell("context", context); condition.SetCell("receiver", context); condition.SetCell("option", r.NewText(arg)); r.ErrorCondition(condition); } } } } if(cwd != null) { r.CurrentWorkingDirectory = cwd; } ((IokeSystem)IokeObject.dataOf(r.System)).CurrentProgram = "-e"; string lib = Environment.GetEnvironmentVariable("ioke.lib"); if(lib == null) { lib = iokeLib; } ((IokeSystem)IokeObject.dataOf(r.System)).AddLoadPath(lib + "/ioke"); ((IokeSystem)IokeObject.dataOf(r.System)).AddLoadPath("lib/ioke"); foreach(string ss in loadDirs) { ((IokeSystem)IokeObject.dataOf(r.System)).AddLoadPath(ss); } foreach(string script in scripts) { r.EvaluateStream("-e", new StringReader(script), message, context); } if(readStdin) { ((IokeSystem)IokeObject.dataOf(r.System)).CurrentProgram = "<stdin>"; r.EvaluateStream("<stdin>", Console.In, message, context); } if(args.Length > start) { if(args.Length > (start+1)) { for(int i=start+1,j=args.Length; i<j; i++) { r.AddArgument(args[i]); } } string file = args[start]; if(file.StartsWith("\"")) { file = file.Substring(1, file.Length-1); } if(file.Length > 1 && file[file.Length-1] == '"') { file = file.Substring(0, file.Length-1); } ((IokeSystem)IokeObject.dataOf(r.System)).CurrentProgram = file; r.EvaluateFile(file, message, context); } else { if(!readStdin && scripts.Count == 0 && !printedSomething) { r.EvaluateString("use(\"builtin/iik\"). IIk mainLoop", message, context); } } r.TearDown(); } catch(ControlFlow.Exit e) { int exitVal = e.ExitValue; try { r.TearDown(); } catch(ControlFlow.Exit e2) { exitVal = e2.ExitValue; } Environment.Exit(exitVal); } catch(ControlFlow e) { string name = e.GetType().FullName; System.Console.Error.WriteLine("unexpected control flow: " + name.Substring(name.LastIndexOf(".") + 1).ToLower()); if(debug) { System.Console.Error.WriteLine(e); } Environment.Exit(1); } }
private IokeObject parseTerminator(int indicator) { int l = lineNumber; int cc = currentCharacter-1; int rr; int rr2; if(indicator == '\r') { rr = peek(); if(rr == '\n') { read(); } } while(true) { rr = peek(); rr2 = peek2(); if((rr == '.' && rr2 != '.') || (rr == '\n')) { read(); } else if(rr == '\r' && rr2 == '\n') { read(); read(); } else { break; } } Message m = new Message(runtime, ".", null, true); m.Line = l; m.Position = cc; return runtime.CreateMessage(m); }