public void Parse(Lisp.Parser parser) { int d = parser.Depth; while(parser.Parse() && parser.Depth >= d) { if(parser.Depth == d+1) { if(parser.Type != Parser.LispType.SYMBOL) throw new Exception("expected SYMBOL at supertux-tiles level, but got \"" + parser.StringValue + "\""); string symbol = parser.SymbolValue; parser.Parse(); switch(symbol) { case "name": Name = parser.StringValue; break; case "tiles": do { Tiles.Add(parser.IntegerValue); } while(parser.Parse() && parser.Type == Parser.LispType.INTEGER); break; default: Console.WriteLine("Unknown section " + symbol); break; } } } }
public void Can_import_into_global_symbols() { var SExprs = Lisp.Parse("(fib 10)"); var lispCtx = Lisp.CreateInterpreter(); try { lispCtx.Eval(SExprs); Assert.Fail("should throw"); } catch (LispEvalException e) {} Lisp.Import(@" (defun fib (n) (if (< n 2) 1 (+ (fib (- n 1)) (fib (- n 2)) ) )) "); lispCtx = Lisp.CreateInterpreter(); Assert.That(lispCtx.Eval(SExprs), Is.EqualTo(89)); Lisp.Reset(); lispCtx = Lisp.CreateInterpreter(); try { lispCtx.Eval(SExprs); Assert.Fail("should throw"); } catch (LispEvalException e) {} }
public void Can_eval_fib_lisp() { var lisp = @" (defun fib (n) (if (< n 2) 1 (+ (fib (- n 1)) (fib (- n 2)) ) )) "; try { var lispCtx = Lisp.CreateInterpreter(); var sExpressions = Lisp.Parse(lisp); var x = lispCtx.Eval(sExpressions); $"{x}".Print(); sExpressions = Lisp.Parse("(fib 15)"); x = lispCtx.Eval(sExpressions); $"{x}".Print(); Assert.That((int)x, Is.EqualTo(987)); } catch (Exception e) { Console.WriteLine(e); throw; } }
public async Task TestDefaultStartingParams() { var startingParams = new LispNode() { new LispNode(1), new LispNode(0), new LispNode(0), new LispNode(1), }; var create = Common.Flatten(await Common.Send(Common.Unflatten(Lisp.Parse("(1 6)")[0]))); var playerKey = create[1][0][1]; var tasks = new List <Task <LispNode> >(); tasks.Add(Common.Send(Common.Unflatten(new LispNode() { new LispNode(2), create[1][0][1], new LispNode() }))); //tasks.Add(Common.Send(Common.Unflatten(new LispNode() { new LispNode(2), playerKey, new LispNode() }))); Task.WaitAll(tasks.ToArray()); var join = Common.Flatten(tasks[0].Result); var start = Common.Flatten(await Common.Send(Common.Unflatten(new LispNode() { new LispNode(3), playerKey, startingParams }))); }
public void TestTreeToList() { var tree = Lisp.Parse("((cons 0) ((cons ((cons 0) ((cons ((cons 0) nil)) ((cons 0) ((cons nil) nil))))) ((cons ((cons ((cons ((cons -1) -3)) ((cons ((cons 0) -3)) ((cons ((cons 1) -3)) ((cons ((cons 2) -2)) ((cons ((cons -2) -1)) ((cons ((cons -1) -1)) ((cons ((cons 0) -1)) ((cons ((cons 3) -1)) ((cons ((cons -3) 0)) ((cons ((cons -1) 0)) ((cons ((cons 1) 0)) ((cons ((cons 3) 0)) ((cons ((cons -3) 1)) ((cons ((cons 0) 1)) ((cons ((cons 1) 1)) ((cons ((cons 2) 1)) ((cons ((cons -2) 2)) ((cons ((cons -1) 3)) ((cons ((cons 0) 3)) ((cons ((cons 1) 3)) nil))))))))))))))))))))) ((cons ((cons ((cons -7) -3)) ((cons ((cons -8) -2)) nil))) ((cons nil) nil)))) nil)))").Children.First(); //var tree = Program.Parse("ap ap cons 42 nil"); //var tree = Program.Parse("ap ap cons 42 ap ap cons ap ap cons 13 ap ap cons 101 nil nil"); //Console.WriteLine(Program.TreeToJson(tree)); }
public void Can_min_max_int_long_double_values() { var lispCtx = Lisp.CreateInterpreter(); Assert.That((int)lispCtx.Eval(Lisp.Parse("(min 1 2)")), Is.EqualTo(1)); Assert.That((int)lispCtx.Eval(Lisp.Parse("(max 1 2)")), Is.EqualTo(2)); Assert.That((double)lispCtx.Eval(Lisp.Parse("(min 1.0 2.0)")), Is.EqualTo(1.0)); Assert.That((double)lispCtx.Eval(Lisp.Parse("(max 1.0 2.0)")), Is.EqualTo(2.0)); Assert.That((long)lispCtx.Eval(Lisp.Parse($"(min {int.MaxValue + 1L} {int.MaxValue + 2L})")), Is.EqualTo(int.MaxValue + 1L)); Assert.That((long)lispCtx.Eval(Lisp.Parse($"(max {int.MaxValue + 1L} {int.MaxValue + 2L})")), Is.EqualTo(int.MaxValue + 2L)); }
public void TestSolver() { var input = "(1 2 () ())"; Program.MakeStartRequest("123", Lisp.Parse(input)[0]); input = "(1 0 (256 0 (512 1 64) (16 128) (350 0 8 1)) ())"; Program.MakeStartRequest("123", Lisp.Parse(input)[0]); input = "(1 1 (256 0 (512 1 64) (16 128) (350 0 8 1)) (0 (16 128) (((1 0 (-48 44) (0 0) (350 0 8 1) 0 64 1) ()) ((0 1 (48 -44) (0 0) (0 16 16 1) 0 64 1) ()))))"; //var output = Program.MakeCommandsRequest("123", Lisp.Parse(input)[0]); //Console.WriteLine(Common.Flatten(output)); input = "(1 1 (256 0 (512 1 64) (16 128) (416 0 0 16)) (1 (16 128) (((1 0 (-47 -11) (1 -1) (415 0 0 16) 8 64 1) ((0 (0 1)))) ((0 1 (46 9) (-2 -1) (127 8 8 1) 0 64 1) ((0 (1 1)))))))"; var gameState = Lisp.Parse(input)[0]; var commands = Program.MakeCommandsRequest( new GameState(gameState[3]), new StaticGameState(gameState[2])); //Assert.AreEqual(commands[0].Vector.X, -1); //Assert.AreEqual(commands[0].Vector.Y, 1); }
private void ParseTileImages(Lisp.Parser parser, ArrayList ImagesList) { if(parser.Type == Parser.LispType.END_LIST) return; int d = parser.Depth; do { ImageRegion region = new ImageRegion(); if(parser.Type == Parser.LispType.STRING) { region.ImageFile = parser.StringValue; } else if(parser.Type == Parser.LispType.START_LIST) { ParseImageRegion(parser, region); } else { throw new Exception("unexpected lisp data: " + parser.Type); } ImagesList.Add(region); } while(parser.Parse() && parser.Depth >= d); }
private void ParseImageRegion(Lisp.Parser parser, ImageRegion region) { parser.Parse(); if(parser.Type != Parser.LispType.SYMBOL) throw new Exception("expected symbol"); if(parser.SymbolValue != "region") throw new Exception("expected region symbol"); parser.Parse(); if(parser.Type != Parser.LispType.STRING) throw new Exception("expected string"); region.ImageFile = parser.StringValue; parser.Parse(); if(parser.Type != Parser.LispType.INTEGER) throw new Exception("expected integer"); region.Region.X = parser.IntegerValue; parser.Parse(); if(parser.Type != Parser.LispType.INTEGER) throw new Exception("expected integer"); region.Region.Y = parser.IntegerValue; parser.Parse(); if(parser.Type != Parser.LispType.INTEGER) throw new Exception("expected integer"); region.Region.Width = parser.IntegerValue; parser.Parse(); if(parser.Type != Parser.LispType.INTEGER) throw new Exception("expected integer"); region.Region.Height = parser.IntegerValue; parser.Parse(); if(parser.Type != Parser.LispType.END_LIST) throw new Exception("expected END_LIST"); }
public void Parse(Lisp.Parser parser) { int d = parser.Depth; while(parser.Parse() && parser.Depth >= d) { if(parser.Depth == d+1) { if(parser.Type != Parser.LispType.SYMBOL) throw new Exception("expected SYMBOL at single tile deserialization level, but found \"" + parser.StringValue + "\""); string symbol = parser.SymbolValue; parser.Parse(); switch(symbol) { case "id": ID = parser.IntegerValue; break; case "images": ParseTileImages(parser, Images); break; case "editor-images": ParseTileImages(parser, EditorImages); break; case "anim-fps": AnimFps = parser.FloatValue; break; case "one-way": OneWayString = parser.StringValue; break; case "data": Data = parser.IntegerValue; break; case "next-tile": NextTile = parser.IntegerValue; break; case "hidden": Hidden = parser.BoolValue; break; case "solid": SetAttribute(Attribute.SOLID, parser.BoolValue); break; case "unisolid": SetAttribute(Attribute.UNISOLID, parser.BoolValue); break; case "ice": SetAttribute(Attribute.ICE, parser.BoolValue); break; case "water": SetAttribute(Attribute.WATER, parser.BoolValue); break; case "slope-type": SetAttribute(Attribute.SLOPE, true); Data = parser.IntegerValue; break; case "hurts": SetAttribute(Attribute.HURTS, parser.BoolValue); break; case "fire": SetAttribute(Attribute.FIRE, parser.BoolValue); break; case "brick": SetAttribute(Attribute.BRICK, parser.BoolValue); break; case "fullbox": SetAttribute(Attribute.FULLBOX, parser.BoolValue); break; case "coin": SetAttribute(Attribute.COIN, parser.BoolValue); break; case "goal": SetAttribute(Attribute.GOAL, parser.BoolValue); break; //Worldmap attributes section - these are stored in Data case "north": SetWMAttribute(Attribute.WORLDMAP_NORTH, parser.BoolValue); break; case "south": SetWMAttribute(Attribute.WORLDMAP_SOUTH, parser.BoolValue); break; case "west": SetWMAttribute(Attribute.WORLDMAP_WEST, parser.BoolValue); break; case "east": SetWMAttribute(Attribute.WORLDMAP_EAST, parser.BoolValue); break; case "stop": SetWMAttribute(Attribute.WORLDMAP_STOP, parser.BoolValue); break; default: Console.WriteLine("Unknown tile element " + symbol); break; } } } }
private void SkipList(Lisp.Parser parser) { int d = parser.Depth; while(parser.Parse() && parser.Depth >= d) ; }
public void ParseTiles(Lisp.Parser parser) { isNew = false; int d = parser.Depth; while(parser.Parse() && parser.Depth >= d) { if(parser.Depth == d && parser.Type != Parser.LispType.START_LIST) { Console.WriteLine("non-cons type in list..."); continue; } if(parser.Depth == d+1) { if(parser.Type != Parser.LispType.SYMBOL) { throw new Exception("Expected symbol in list element"); } switch(parser.SymbolValue) { case "properties": SkipList(parser); break; case "tilegroup": TileGroup tilegroup = new TileGroup(); tilegroup.Parse(parser); TileGroups.Add(tilegroup); break; case "tile": Tile tile = new Tile(); tile.Parse(parser); while(tile.ID >= Tiles.Count) Tiles.Add(null); Tiles[tile.ID] = tile; break; case "tiles": ParseMoreTiles(parser); isNew = true; break; default: throw new Exception("Unexpected listentry: " + parser.SymbolValue); } } } }
public void ParseMoreTiles(Lisp.Parser parser) { int blockWidth = 0; int blockHeight = 0; List<int> ids = new List<int>(); List<int> attributes = new List<int>(); List<int> datas = new List<int>(); List<string> imageNames = new List<string>(); float animFps = 0; int d = parser.Depth; while(parser.Parse() && parser.Depth >= d) { if(parser.Depth == d+1) { if(parser.Type != Parser.LispType.SYMBOL) throw new Exception("expected SYMBOL at supertux-tiles---tiles level, but got \"" + parser.StringValue + "\""); string symbol = parser.SymbolValue; parser.Parse(); switch(symbol) { case "width": blockWidth = parser.IntegerValue; break; case "height": blockHeight = parser.IntegerValue; break; case "ids": Parser.ParseIntList(parser, ids); break; case "attributes": Parser.ParseIntList(parser, attributes); break; case "datas": Parser.ParseIntList(parser, datas); break; case "anim-fps": animFps = parser.FloatValue; break; case "image": int subDepth = parser.Depth; while(parser.Depth >= subDepth) { imageNames.Add(parser.StringValue); parser.Parse(); } break; default: Console.WriteLine("Unknown tiles element " + symbol); break; } } } if(ids.Count != blockWidth * blockHeight) throw new ApplicationException("Must have width*height ids in tiles block, but found " + ids.Count.ToString()); if((attributes.Count != blockWidth * blockHeight) && attributes.Count > 0) //missing atributes == all-are-0-attributes throw new ApplicationException("Must have width*height attributes in tiles block"); if((datas.Count != blockWidth * blockHeight) && datas.Count > 0) //missing DATAs == all-are-0-DATAs throw new ApplicationException("Must have width*height DATAs in tiles block"); int id = 0; for(int y = 0; y < blockHeight; ++y) { for(int x = 0; x < blockWidth; ++x) { if (ids[id] != 0) { Tile tile = new Tile(); tile.Images = new ArrayList(); foreach (string str in imageNames) { ImageRegion region = new ImageRegion(); region.ImageFile = str; region.Region.X = x * TILE_WIDTH; region.Region.Y = y * TILE_HEIGHT; region.Region.Width = TILE_WIDTH; region.Region.Height = TILE_HEIGHT; tile.Images.Add(region); } tile.ID = ids[id]; tile.Attributes = (attributes.Count > 0)?attributes[id]:0; //missing atributes == all-are-0-attributes tile.Data = (datas.Count > 0)?datas[id]:0; //missing DATAs == all-are-0-DATAs tile.AnimFps = animFps; while(Tiles.Count <= tile.ID) Tiles.Add(null); Tiles[tile.ID] = tile; } id++; } } }
public void Parse(Lisp.Parser parser) { int d = parser.Depth; while(parser.Parse() && parser.Depth >= d) { if(parser.Depth == d+1) { if(parser.Type != Parser.LispType.SYMBOL) throw new Exception("expected SYMBOL"); string symbol = parser.SymbolValue; parser.Parse(); switch(symbol) { case "id": ID = parser.IntegerValue; break; case "images": ParseTileImages(parser); break; case "editor-images": EditorImage = parser.StringValue; break; case "solid": Solid = parser.BoolValue; break; case "unisolid": UniSolid = parser.BoolValue; break; case "ice": Ice = parser.BoolValue; break; case "water": Water = parser.BoolValue; break; case "slope-type": Slope = true; Data = parser.IntegerValue; break; case "anim-fps": AnimFps = parser.FloatValue; break; case "hurts": Hurts = parser.BoolValue; break; case "hidden": Hidden = parser.BoolValue; break; case "data": Data = parser.IntegerValue; break; case "next-tile": NextTile = parser.IntegerValue; break; case "brick": Brick = parser.BoolValue; break; case "fullbox": FullBox = parser.BoolValue; break; case "coin": Coin = parser.BoolValue; break; case "goal": Goal = parser.BoolValue; break; default: Console.WriteLine("Unknown tile element " + symbol); break; } } } }
public void Can_eval_lisp_in_lisp() { var lisp = @" ;;; A circular Lisp interpreter in Common/Emacs/Nukata Lisp ;;; by SUZUKI Hisao on H28.8/10, H29.3/13 ;;; cf. Zick Standard Lisp (https://github.com/zick/ZickStandardLisp) (progn ;; Expr: (EXPR environment (symbol...) expression...) ;; Subr: (SUBR . function) ;; Environment: ((symbol . value)...) ;; N.B. Expr has its own environment since this Lisp is lexically scoped. ;; Language-specific Hacks (setq funcall (lambda (f x) (f x))) ; for Nukata Lisp and this Lisp (setq max-lisp-eval-depth 10000) ; for Emacs Lisp (setq max-specpdl-size 7000) ; for Emacs Lisp ;; The global environment of this Lisp (setq global-env (list '(*version* . (1.2 ""Lisp"" ""circlisp"")) (cons 'car (cons 'SUBR (lambda (x) (car (car x))))) (cons 'cdr (cons 'SUBR (lambda (x) (cdr (car x))))) (cons 'cons (cons 'SUBR (lambda (x) (cons (car x) (cadr% x))))) (cons 'eq (cons 'SUBR (lambda (x) (eq (car x) (cadr% x))))) (cons 'atom (cons 'SUBR (lambda (x) (atom (car x))))) (cons 'rplaca (cons 'SUBR (lambda (x) (rplaca (car x) (cadr% x))))) (cons 'rplacd (cons 'SUBR (lambda (x) (rplacd (car x) (cadr% x))))) (cons 'list (cons 'SUBR (lambda (x) x))) (cons '+ (cons 'SUBR (lambda (x) (+ (car x) (cadr% x))))) (cons '* (cons 'SUBR (lambda (x) (* (car x) (cadr% x))))) (cons '- (cons 'SUBR (lambda (x) (- (car x) (cadr% x))))) (cons 'truncate (cons 'SUBR (lambda (x) (truncate (car x) (cadr% x))))) (cons 'mod (cons 'SUBR (lambda (x) (mod (car x) (cadr% x))))) (cons '= (cons 'SUBR (lambda (x) (= (car x) (cadr% x))))) (cons '< (cons 'SUBR (lambda (x) (< (car x) (cadr% x))))) (cons 'print (cons 'SUBR (lambda (x) (print (car x))))) (cons 'apply (cons 'SUBR (lambda (x) (apply% (car x) (cadr% x))))) (cons 'eval (cons 'SUBR (lambda (x) (eval% (car x) global-env)))))) (defun caar% (x) (car (car x))) (defun cadr% (x) (car (cdr x))) (defun cddr% (x) (cdr (cdr x))) (defun caddr% (x) (car (cdr (cdr x)))) (defun cdddr% (x) (cdr (cdr (cdr x)))) (defun cadddr% (x) (car (cdr (cdr (cdr x))))) (defun assq% (key alist) ; cf. Emacs/Nukata Lisp (if alist (if (eq key (caar% alist)) (car alist) (assq% key (cdr alist))) nil)) (defun pairlis% (keys data alist) ; cf. Common Lisp (if keys (cons (cons (car keys) (car data)) (pairlis% (cdr keys) (cdr data) alist)) alist)) ;; Define symbol as value in the global environment. (defun global-def (sym val) (rplacd global-env (cons (car global-env) (cdr global-env))) (rplaca global-env (cons sym val))) (defun eval% (e env) (if (atom e) ((lambda (var) (if var (cdr var) e)) (assq% e env)) (if (eq (car e) 'quote) ; (quote e) (cadr% e) (if (eq (car e) 'if) ; (if e e e) (if (eval% (cadr% e) env) (eval% (caddr% e) env) (eval% (cadddr% e) env)) (if (eq (car e) 'progn) ; (progn e...) (eval-progn (cdr e) env nil) (if (eq (car e) 'lambda) ; (lambda (v...) e...) (make-closure env (cdr e)) (if (eq (car e) 'defun) ; (defun f (v...) e...) (global-def (cadr% e) (make-closure env (cddr% e))) (if (eq (car e) 'setq) ; (setq v e) ((lambda (var value) (if var (rplacd var value) (global-def (cadr% e) value)) value) (assq% (cadr% e) env) (eval% (caddr% e) env)) (apply% (eval% (car e) env) ; (f e...) (evlis (cdr e) env)))))))))) ;; (make-closure env '((v...) e...)) => (EXPR env (v...) e...) (defun make-closure (env ve) (cons 'EXPR (cons env ve))) ;; (eval-progn '((+ 1 2) 3 (+ 4 5)) global-env nil) => 9 (defun eval-progn (x env result) (if x (if (cdr x) (eval-progn (cdr x) env (eval% (car x) env)) (eval% (car x) env)) result)) ;; (evlis '((+ 1 2) 3 (+ 4 5)) global-env) => (3 3 9) (defun evlis (x env) (if x (cons (eval% (car x) env) (evlis (cdr x) env)) nil)) (defun apply% (fun arg) (if (eq (car fun) 'EXPR) ; (EXPR env (v...) e...) (eval-progn (cdddr% fun) (pairlis% (caddr% fun) arg (cadr% fun)) nil) (if (eq (car fun) 'SUBR) ; (SUBR . f) (funcall (cdr fun) arg) fun))) (defun global-eval (e) (eval% e global-env)) (global-eval (quote ;; -- WRITE YOUR EXPRESSION HERE -- (progn (defun fib (n) (if (< n 2) 1 (+ (fib (- n 1)) (fib (- n 2))))) (print (fib 10))) ;; -------------------------------- ))) "; try { var lispCtx = Lisp.CreateInterpreter(); var sExpressions = Lisp.Parse(lisp); var x = lispCtx.Eval(sExpressions); Assert.That((int)x, Is.EqualTo(89)); } catch (Exception e) { Console.WriteLine(e); throw; } }
public PathNode(Lisp.Parser parser) { int d = parser.Depth; while (parser.Parse() && parser.Depth >= d) { if (parser.Depth == d + 1) { if (parser.Type != Lisp.Parser.LispType.SYMBOL) throw new Exception("expected SYMBOL"); string symbol = parser.SymbolValue; parser.Parse(); switch (symbol) { case "x": this.x = parser.FloatValue; break; case "y": this.x = parser.FloatValue; break; case "time": this.x = parser.FloatValue; break; default: throw new Exception("Unknown Token in Path Node"); } } } }