(in-package :monkey) (defun make-tokens (&rest tokens) (loop :for token :in tokens :if (consp token) :collect (make-token (car token) (cadr token)) :if (typep token 'token-type) :collect (as-token token))) (defun test-lexer (str expect) (let ((lexer (make-lexer str))) (not (find nil (mapcar #'token= (lexer-tokens lexer) expect))))) (defun test-1 () (test-lexer "=+(){},;" (make-tokens :t/= :t/+ :t/lparen :t/rparen :t/lbrace :t/rbrace :t/comma :t/semicolon :t/eof))) (defun test-2 () (test-lexer "let five = 5; let ten = 10; let add = fn(x, y) { x + y; }; let result = add(five, ten); !-/*; 5 < 10 > 5; if (5 < 10) { return true; } else { return false; } 10 == 10; 10 != 9; " (make-tokens :t/let (list :t/ident "five") :t/= (list :t/int "5") :t/semicolon :t/let (list :t/ident "ten") :t/= (list :t/int "10") :t/semicolon :t/let (list :t/ident "add") :t/= :t/function :t/lparen (list :t/ident "x") :t/comma (list :t/ident "y") :t/rparen :t/lbrace (list :t/ident "x") :t/+ (list :t/ident "y") :t/rbrace :t/semicolon :t/let (list :t/ident "result") :t/= (list :t/ident "add") :t/lparen (list :t/ident "five") :t/comma (list :t/ident "ten") :t/rparen :t/semicolon :t/! :t/- :t// :t/* :t/semicolon (list :t/int "5") :t/< (list :t/int "10") :t/> (list :t/int "5") :t/semicolon (list :t/if "if") :t/lparen (list :t/int "5") :t/< (list :t/int "10") :t/rparen :t/lbrace :t/return :t/true :t/semicolon :t/rbrace :t/else :t/lbrace :t/return :t/false :t/semicolon :t/rbrace (list :t/int "10") :t/== (list :t/int "10") :t/semicolon (list :t/int "10") :t/!= (list :t/int "9") :t/semicolon :t/eof "")))