lasp 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 09308a13fbaaa0866f4e0f71c3e9bda5b3f68175
4
- data.tar.gz: 8dc8898d8ad6b1eef27801d566a8b963ab7186cb
3
+ metadata.gz: faac6a5058ca029f9afae76c17751e3d59969524
4
+ data.tar.gz: 92451a7973baef4b40ecaa7b8af4c1ea3b5192aa
5
5
  SHA512:
6
- metadata.gz: 1df013030f0c92ed76d5cf748d640007b9e11446099d9b68ca0c65ce0247743b8c99013a0efa4fc14db22e795372e87462e746b944ce3cd72406aa02c8549740
7
- data.tar.gz: a7725ebe46569683d44f88031665bbbb987d68e462fb459a44b1b64e0c05b3d292f00190df9e7bd95be10768e881a63397f341daa483fdd2bda9fe9d33a6ab92
6
+ metadata.gz: 65e6433d37ab903dc463d0704ee5864c7c289829f77d0cbdc8dcbe7c9bee6aba3a80013c4a2b6d40c4b183475f00b47d09de3a7167e5f36f4a24c155146ef411
7
+ data.tar.gz: de567b39199ea999e5331d78686c88237ce8b307b33a944b3308339b9cbaa70a6bfc7e20fa4e0ecf52d2ee31379150266a718e37d33e2e0343eaa5a04626c25f
@@ -1,5 +1,18 @@
1
1
  # Läsp changelog
2
2
 
3
+ ## v0.10.0 - 2016-02-22
4
+
5
+ ### Added
6
+
7
+ - Allow escape characters in strings
8
+ - `\n` - newline
9
+ - `\t` - tab
10
+ - `\"` - double quote
11
+ - `\\` - backslash
12
+ - Allow `print` and `println` to take any number of arguments
13
+ - Add text function to stdlib for easier concatenation (works the same as
14
+ `print` and `println` now do but returns a string)
15
+
3
16
  ## v0.9.0 - 2016-02-20
4
17
 
5
18
  ### Added
@@ -431,24 +431,18 @@ Returns the inverted truthiness of its argument.
431
431
 
432
432
  ### print
433
433
 
434
- Prints its argument to stdout and returns `nil`.
434
+ Prints its arguments to stdout and returns `nil`.
435
435
 
436
- ```clojure
437
- (do
438
- (print "Hello ")
439
- (print "world!")) ; => nil
436
+ See also [println](#println) to print a line of output.
440
437
 
438
+ ```clojure
439
+ (print "Hello ")
440
+ (print "world!\n") ; Manually add a newline
441
441
  ;; Hello world!
442
- ```
443
-
444
-
445
- ### println
446
-
447
- Prints its argument and a newline to stdout and returns `nil`.
448
442
 
449
- ```clojure
450
- (println "Hello World!") ; => nil
451
- ;; Hello World!
443
+ ; It also takes several arguments and prints them after each other:
444
+ (print "Hello " "world!")
445
+ ;; Hello world!
452
446
  ```
453
447
 
454
448
 
@@ -777,6 +771,15 @@ Take a list of every Nth item in a list.
777
771
  ```
778
772
 
779
773
 
774
+ ### text
775
+
776
+ Create a string by concatenating all arguments.
777
+
778
+ ```clojure
779
+ (text "one " 1 ", two " 2) ; => "one 1, two 2"
780
+ ```
781
+
782
+
780
783
  ### text->list
781
784
 
782
785
  Turn a text into a list of its characters.
@@ -855,6 +858,21 @@ Request an answer to a question from a terminal user.
855
858
  ```
856
859
 
857
860
 
861
+ ### println
862
+
863
+ Prints each of its arguments to stdout on a line and returns `nil`.
864
+
865
+ ```clojure
866
+ (println "Hello World!")
867
+ ;; Hello World!
868
+
869
+ (println "Hello " "World!")
870
+ ;; Hello World!
871
+
872
+ (println) ; Prints a newline
873
+ ```
874
+
875
+
858
876
  ### defn
859
877
 
860
878
  A shorthand macro for defining a function. As a bonus it also wraps
@@ -20,8 +20,7 @@ module Lasp
20
20
  :assoc => -> (a, key, val) { a.dup.tap { |a| a[key] = val } },
21
21
  :dissoc => -> (a, key) { a.dup.tap { |a| a.delete(key) } },
22
22
  :not => -> (arg) { !arg },
23
- :print => -> (output) { STDOUT.print(output) },
24
- :println => -> (output) { STDOUT.puts(output) },
23
+ :print => -> (*output) { STDOUT.print(*output) },
25
24
  :readln => -> () { STDIN.gets.chomp },
26
25
  :apply => -> (f, list) { f.call(*list) },
27
26
  :"." => -> (obj, m, *args) { obj.send(m, *args) },
@@ -0,0 +1,44 @@
1
+ require "strscan"
2
+
3
+ class Lexer
4
+ TOKENS = [
5
+ /\(|\)/, # parens
6
+ /'/, # quote
7
+ /"(\\"|[^"])*"/, # string literal
8
+ /[^\s)]+/, # any non-whitespace character excluding )
9
+ ]
10
+
11
+ def self.tokenize(program)
12
+ new(program).tokenize
13
+ end
14
+
15
+ def initialize(program)
16
+ @scanner = StringScanner.new(sanitize(program))
17
+ end
18
+
19
+ def tokenize
20
+ tokens = []
21
+ while (token = read_token)
22
+ tokens << token
23
+ end
24
+ tokens
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :scanner
30
+
31
+ def read_token
32
+ scanner.skip(/\s+/)
33
+ return if scanner.eos?
34
+
35
+ TOKENS.each do |token|
36
+ return scanner.scan(token) if scanner.match?(token)
37
+ end
38
+ end
39
+
40
+ def sanitize(string)
41
+ # Remove comments
42
+ string.gsub(/;.*$/, "")
43
+ end
44
+ end
@@ -1,15 +1,24 @@
1
+ require "lasp/lexer"
2
+
1
3
  module Lasp
2
4
  class Parser
5
+ ESCAPE_CHARACTERS = {
6
+ '\n' => "\n",
7
+ '\t' => "\t",
8
+ '\\\\' => "\\",
9
+ '\"' => "\"",
10
+ }
11
+
3
12
  def self.parse(program)
4
13
  new.parse(program)
5
14
  end
6
15
 
7
16
  def parse(program)
8
- build_ast(tokenize(sanitize(program)))
17
+ build_ast(tokenize(program))
9
18
  end
10
19
 
11
- def tokenize(string)
12
- string.scan(/(?:(?:[^\s"()']|"[^"]*")+|[()'])/)
20
+ def tokenize(program)
21
+ Lexer.tokenize(program)
13
22
  end
14
23
 
15
24
  private
@@ -45,14 +54,14 @@ module Lasp
45
54
  when "nil" then nil
46
55
  when /\A-?\d+\z/ then Integer(token)
47
56
  when /\A-?\d+.\d+\z/ then Float(token)
48
- when /"(.*)"/ then String($1)
57
+ when /"(.*)"/ then String(unescape($1))
49
58
  when /:([^\s]+)/ then String($1) # Symbol style strings are actually just strings
50
59
  else token.to_sym
51
60
  end
52
61
  end
53
62
 
54
- def sanitize(string)
55
- string.gsub(/;.*$/, "")
63
+ def unescape(string)
64
+ string.gsub(/\\(.)/) { |match| ESCAPE_CHARACTERS.fetch(match, $1) }
56
65
  end
57
66
  end
58
67
  end
@@ -1,5 +1,5 @@
1
1
  require "lasp"
2
- require "lasp/parser"
2
+ require "lasp/lexer"
3
3
  require "readline"
4
4
 
5
5
  module Lasp
@@ -28,7 +28,7 @@ module Lasp
28
28
  private
29
29
 
30
30
  def autoclose_parentheses(input)
31
- tokens = Parser.new.tokenize(input)
31
+ tokens = Lexer.tokenize(input)
32
32
  num_opens = tokens.select { |t| t == "(" }.count
33
33
  num_closes = tokens.select { |t| t == ")" }.count
34
34
 
@@ -154,6 +154,10 @@
154
154
  (def ->decimal (ruby-method :to_f)) ; Convert to decimal
155
155
 
156
156
 
157
+ ; Create a string by concatenating all arguments
158
+ (defn text (& args)
159
+ (list->text args))
160
+
157
161
  ; Pass a value in order through a list of functions
158
162
  (defn pipe (item & fns)
159
163
  (if (empty? fns)
@@ -170,3 +174,7 @@
170
174
  (defn prompt (question)
171
175
  (print question)
172
176
  (readln))
177
+
178
+ ; Print with a newline
179
+ (defn println (& args)
180
+ (print (+ (list->text args) "\n")))
@@ -1,3 +1,3 @@
1
1
  module Lasp
2
- VERSION = "0.9.0"
2
+ VERSION = "0.10.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lasp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jimmy Börjesson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-20 00:00:00.000000000 Z
11
+ date: 2016-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -63,6 +63,7 @@ files:
63
63
  - lib/lasp/ext.rb
64
64
  - lib/lasp/fn.rb
65
65
  - lib/lasp/interpreter.rb
66
+ - lib/lasp/lexer.rb
66
67
  - lib/lasp/macro.rb
67
68
  - lib/lasp/params.rb
68
69
  - lib/lasp/parser.rb