spitewaste 0.1.001 → 0.1.002

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c2124fde880a571c835efe1e74e397a0dea698786c69a62852c4ad8bd7e3ffe0
4
- data.tar.gz: 0d40e036ca0d7f51ea617be600274088160a8159dc7e04f87af8429d29154fc4
3
+ metadata.gz: b185ba760bbddf427962b292046de239f29b6a13964c7182eea2da1a2bcc0d10
4
+ data.tar.gz: 36991071a4e6bc98134d235a340dbaf90f082020ffc2e2bd8a67b83970b86e68
5
5
  SHA512:
6
- metadata.gz: 8ca420c6896dba0743f70f27a6558178bfe6201fd821afd45594e11796a975ebd042eb6d65fda6b20221f40831d183e417aca2e7dd7c19edff16c4e99ea15135
7
- data.tar.gz: 1699a938795047284088697c7c3d7f444e626b033f888080618d2d7350635a69dab37b63455cd6544740e747b2665f30df5c15d14c64bdb1a2f2755387cd4ff5
6
+ metadata.gz: add4543eead4effe21e7eab4ff3bd18fc6f544889368c14b2b178953adddbb1f53913dc737ebcb95ce5f49ee144c81e1916072e2c9e72752c5cb9aab5d0313d5
7
+ data.tar.gz: 1249b0e70507839d31c15f7fb29d084eb7b572dea51f5b398416e871b57e5d3eb621e2ed756cd5871a28a8a7ebd72bc59f1b65a8b884a441dc9de77a3e254271
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
3
+
4
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
5
+
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
9
+
10
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
+
13
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
data/README.md CHANGED
@@ -1,7 +1,4 @@
1
- <p align="center">
2
- <img src="abc" /><br >
3
- "Code should be invisible." — someone, surely
4
- </p>
1
+ <p align="center">"Code should be invisible." — someone, surely</p>
5
2
 
6
3
  # Spitewaste
7
4
 
@@ -21,7 +18,7 @@ Spitewaste is the pseudo-assembly language referred to throughout this document,
21
18
 
22
19
  **spw** is a command-line utility whose primary purpose is to "lower" Spitewaste programs to Whitespace for execution by some external interpreter, but it's capable of several (perhaps too many) other transformations; see `spw help convert` for further details. In addition to losslessly converting between various representations, spw can generate pretty pictures of Whitespace code syntax-highlighted in your favorite color scheme via `spw image`.
23
20
 
24
- Spitewaste is not [a Whitespace interpreter](collidedscope/spiceweight), but `spw exec` will convert its input to something your interpreter of choice should understand and ferry it along. Finally, `spw compile` will blindly translate Whitespace instructions to functionally equivalent C++ code and feed that into a compiler; the results aren't spectacular (compilers loathe `goto`), but it's fun to pretend Whitespace is a compiled language.
21
+ Spitewaste is not [a Whitespace interpreter](../../../spiceweight), but `spw exec` will convert its input to something your interpreter of choice should understand and ferry it along. Finally, `spw compile` will blindly translate Whitespace instructions to functionally equivalent C++ code and feed that into a compiler; the results aren't spectacular (compilers loathe `goto`), but it's fun to pretend Whitespace is a compiled language.
25
22
 
26
23
  ## Where <sub>can I get it?</sub>
27
24
 
data/Rakefile CHANGED
@@ -1,10 +1,64 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'rake/testtask'
3
+ require 'json'
3
4
 
4
5
  Rake::TestTask.new(:test) do |t|
5
6
  t.libs << 'test'
6
- t.libs << 'lib'
7
7
  t.test_files = FileList['test/*_test.rb']
8
8
  end
9
9
 
10
- task :default => :test
10
+ desc "Generate standard library documentation."
11
+ task :docs do |t|
12
+ all_docs = {}
13
+ Dir['lib/spitewaste/libspw/math*'].each do |path|
14
+ lib = File.basename path, '.spw'
15
+ all_docs[lib] = extract_docs path
16
+ end
17
+ File.open('docs.json', ?w) { |f| JSON.dump all_docs, f }
18
+ end
19
+
20
+ def extract_docs path
21
+ docs = {}
22
+ buffer = ''
23
+
24
+ File.open(path).each_line do |line|
25
+ if line.strip.empty?
26
+ buffer.clear
27
+ elsif line[/^([^_]\S+):/]
28
+ docs[$1] = parse_doc buffer.dup unless buffer.empty?
29
+ buffer.clear
30
+ elsif line[/^;/]
31
+ buffer << line
32
+ end
33
+ end
34
+
35
+ docs
36
+ end
37
+
38
+ StackRx = /(?<=\[)[^\]]+(?=\])/
39
+
40
+ def strpack s
41
+ s.bytes.zip(0..).sum { |b, e| b * 128 ** e }
42
+ end
43
+
44
+ def parse_stack s
45
+ s.split.map { Integer(_1) rescue strpack _1.delete %('") }
46
+ end
47
+
48
+ def parse_doc doc
49
+ # strip comment character and any implementation details
50
+ doc.gsub!(/; */, '').gsub!(/^!.+\n/, '')
51
+
52
+ head, specs = doc.split "\n\n"
53
+ *desc, effect = head.split ?\n
54
+ desc *= ?\n
55
+
56
+ cases = []
57
+ specs.scan(StackRx).each_slice 2 do |spec|
58
+ cases << spec.map { parse_stack _1 }
59
+ end if specs
60
+
61
+ {full: doc, desc: desc, effect: effect, cases: cases}
62
+ end
63
+
64
+ task default: :test
@@ -120,6 +120,6 @@ A standard library! Writing a Whitespace program from scratch can be a daunting
120
120
 
121
121
  ### Strings
122
122
 
123
- Pretty much every program needs strings, and Spitewaste has 'em! But how? Well, a string is ultimately just a sequence of bytes, and we can use the power of exponents to smush multiple numbers into a single value. If we had the numbers 3, 9, and 4, we could easily encode them as a single base-10 number: 3 × 10<sup>2</sup> + 9 × 10<sup>1</sup> + 4 × 10<sup>0</sup>. Strings in Spitewaste are similarly encoded, except backwards (as an implementation detail) and in base-128 rather than decimal.
123
+ Pretty much every program needs strings, and Spitewaste has 'em! But how? Well, a string is ultimately just a sequence of bytes, and we can use the power of exponents to smush multiple numbers into a single value. If we had the numbers 3, 9, and 4, we could easily encode them as a single base-10 number: 3 × 10<sup>2</sup> + 9 × 10<sup>1</sup> + 4 × 10<sup>0</sup> = 394. Strings in Spitewaste are similarly encoded, except backwards (as an implementation detail) and in base-128 rather than decimal.
124
124
 
125
125
  When you say <code>push "ABC"</code>, the assembler transforms it into <code>push 1106241</code>, the value of: 67 ('C') × 128<sup>2</sup> + 66 × 128<sup>1</sup> + 65 × 128<sup>0</sup>. Whitespace interpreters SHOULD (and many do) support arbitrarily large integers, so we don't have to worry about these representations not fitting into 64 bits. Once we're able to pass strings around as individual values, a plethora of possibilities opens up, and the standard library contains many string functions to reflect this.
@@ -1,7 +1,7 @@
1
1
  module Spitewaste
2
2
  class AssemblyEmitter < Emitter
3
3
  def emit io:
4
- io.puts instructions.map { (_1 * ' ').rstrip }
4
+ io.puts instructions.map { |i| (i * ' ').rstrip }
5
5
  end
6
6
  end
7
7
  end
@@ -1,52 +1,55 @@
1
- import util (range) ; for factorial
2
-
3
- ; [b e] => [b^e]
4
- pow:
5
- push 1 swap
6
-
1
+ import util ; range for factorial, inc for ilog
2
+
3
+ ; returns B raised to the power E
4
+ ; [B E] => [B**E]
5
+ ;
6
+ ; [0 0] => [1], [0 9] => [0], [9 0] => [1]
7
+ ; [3 2] => [9], [2 3] => [8], [7 4] => [2401]
8
+ pow: push 1 swap
7
9
  _pow_loop: ; [b n e]
8
10
  dup jz _pow_done
9
11
  swap copy 2 mul ; [b e n*b]
10
12
  swap push 1 sub jump _pow_loop
13
+ _pow_done: swap slide 2 ret
11
14
 
12
- _pow_done: ; b n e
13
- pop slide 1 ret
14
-
15
- ;;;
16
-
17
- ; [n] => [n!]
15
+ ; returns the product of the integers from 1 to N, with 0! defined to be 1
16
+ ; [N] => [N!]
17
+ ;
18
+ ; [0] => [1], [1] => [1], [2] => [2]
19
+ ; [3] => [6], [5] => [120], [10] => [3628800]
18
20
  factorial: push 0 swap :range
19
21
  _fac_loop: swap dup jz _fac_done mul jump _fac_loop
20
- _fac_done: pop ret
21
22
 
22
- ;;;
23
+ _fac_done: pop ret
23
24
 
24
- isqrt: ; [n] -> [isqrt(n)]
25
- dup push 2 sub jn _isqrt_done
26
- dup push 4 div :isqrt push 2 mul
27
- dup push 1 add
28
- copy 2 copy 1 dup mul sub jn _isqrt_cleanup
29
- swap
30
- _isqrt_cleanup: swap slide 2
25
+ ; returns the integer square root of N
26
+ ; [N] => [floor(sqrt(N))]
27
+ ;
28
+ ; [0] => [0], [1] => [1], [2] => [1], [3] => [1]
29
+ ; [4] => [2], [8] => [2], [9] => [3], [99] => [9], [100] => [10]
30
+ isqrt:
31
+ dup push 2 sub jn _isqrt_done ; nothing to do for 0 and 1
32
+ dup push 2 div
33
+ _isqrt_loop:
34
+ copy 1 copy 1 div copy 1 add push 2 div ; new guess is (n / g + g) / 2
35
+ dup copy 2 sub jn _isqrt_update
36
+ swap slide 2
31
37
  _isqrt_done: ret
32
-
33
- ;;;
34
-
35
- ; intger logarithm ; [a b] => [log(a, b)]
36
- ; ! clobbers heap address -1 TODO: maybe not necessary?
37
- ilog:
38
- push -1 push 0 store ; tally
39
-
40
- _ilog_loop: ; a b
38
+ _isqrt_update: slide 1 jump _isqrt_loop
39
+
40
+ ; returns the intger logarithm of N in base B
41
+ ; ! clobbers heap address -1 TODO: maybe unnecessarily?
42
+ ; [N B] => [logB(N)]
43
+ ;
44
+ ; [15 4] => [1], [16 4] => [2]
45
+ ; [100 10] => [2]
46
+ ; [42 2] => [5]
47
+ ilog: push -1,0 store ; accumulator at -1
48
+ _ilog_loop:
41
49
  swap dup jz _ilog_done
42
50
  push -1 :inc
43
- copy 1 div swap
44
- jump _ilog_loop
45
-
46
- _ilog_done: ; a b t
47
- push -1 load slide 2 ret
48
-
49
- ;;;
51
+ copy 1 div swap jump _ilog_loop
52
+ _ilog_done: push -1 load slide 2 ret
50
53
 
51
54
  ; greatest common divisor
52
55
  gcd: ; [a b]
@@ -66,6 +66,7 @@ SPW
66
66
 
67
67
  'minby' => 'maxby (%2$s push -1 mul)',
68
68
  'each' => 'dup times (dup call roll %2$s push 1 sub) pop',
69
+ 'count' => 'select (%2$s) dup call nslide',
69
70
  'select' => generate_filter_spw('select', 0, 1),
70
71
  'reject' => generate_filter_spw('reject', 1, 0),
71
72
  }
@@ -100,7 +100,7 @@ module Spitewaste
100
100
  end
101
101
 
102
102
  def remove_comments
103
- @src.gsub!(/;.+/, '')
103
+ @src.gsub!(/;.*/, '')
104
104
  end
105
105
 
106
106
  def add_sugar
@@ -109,7 +109,7 @@ module Spitewaste
109
109
  # character literals
110
110
  @src.gsub!(/'(.)'/) { $1.ord }
111
111
  # quick push (`push 1,2,3` desugars to individual pushes)
112
- @src.gsub!(/push \S+/) { _1.split(?,) * ' push ' }
112
+ @src.gsub!(/push \S+/) { |m| m.split(?,) * ' push ' }
113
113
  end
114
114
 
115
115
  def gensym
@@ -1,3 +1,3 @@
1
1
  module Spitewaste
2
- VERSION = '0.1.001'
2
+ VERSION = '0.1.002'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spitewaste
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.001
4
+ version: 0.1.002
5
5
  platform: ruby
6
6
  authors:
7
7
  - Collided Scope (collidedscope)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-12 00:00:00.000000000 Z
11
+ date: 2020-12-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Spitewaste is a collection of tools that makes it almost too easy to
14
14
  write Whitespace.
@@ -19,6 +19,7 @@ extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
21
  - Gemfile
22
+ - LICENSE
22
23
  - README.md
23
24
  - Rakefile
24
25
  - TUTORIAL.md