pygments.rb 0.3.7 → 0.4.1

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.
Files changed (139) hide show
  1. data/CHANGELOG +9 -0
  2. data/CHANGELOG.md +6 -0
  3. data/LICENSE +1 -1
  4. data/README.md +1 -1
  5. data/lexers +0 -0
  6. data/lib/pygments/version.rb +1 -1
  7. data/test/test_pygments.rb +0 -1
  8. data/vendor/pygments-main/AUTHORS +14 -1
  9. data/vendor/pygments-main/CHANGES +56 -6
  10. data/vendor/pygments-main/LICENSE +1 -1
  11. data/vendor/pygments-main/Makefile +1 -1
  12. data/vendor/pygments-main/REVISION +1 -0
  13. data/vendor/pygments-main/docs/generate.py +1 -1
  14. data/vendor/pygments-main/docs/src/api.txt +1 -1
  15. data/vendor/pygments-main/docs/src/index.txt +1 -1
  16. data/vendor/pygments-main/docs/src/integrate.txt +5 -0
  17. data/vendor/pygments-main/docs/src/java.txt +70 -0
  18. data/vendor/pygments-main/external/autopygmentize +64 -0
  19. data/vendor/pygments-main/external/markdown-processor.py +2 -2
  20. data/vendor/pygments-main/external/moin-parser.py +1 -1
  21. data/vendor/pygments-main/external/rst-directive-old.py +1 -1
  22. data/vendor/pygments-main/external/rst-directive.py +1 -1
  23. data/vendor/pygments-main/pygments/__init__.py +2 -2
  24. data/vendor/pygments-main/pygments/cmdline.py +14 -6
  25. data/vendor/pygments-main/pygments/console.py +1 -1
  26. data/vendor/pygments-main/pygments/filter.py +1 -1
  27. data/vendor/pygments-main/pygments/filters/__init__.py +1 -1
  28. data/vendor/pygments-main/pygments/formatter.py +1 -1
  29. data/vendor/pygments-main/pygments/formatters/__init__.py +1 -1
  30. data/vendor/pygments-main/pygments/formatters/_mapping.py +1 -1
  31. data/vendor/pygments-main/pygments/formatters/bbcode.py +1 -1
  32. data/vendor/pygments-main/pygments/formatters/html.py +73 -2
  33. data/vendor/pygments-main/pygments/formatters/img.py +1 -1
  34. data/vendor/pygments-main/pygments/formatters/latex.py +1 -1
  35. data/vendor/pygments-main/pygments/formatters/other.py +1 -1
  36. data/vendor/pygments-main/pygments/formatters/rtf.py +1 -1
  37. data/vendor/pygments-main/pygments/formatters/svg.py +1 -1
  38. data/vendor/pygments-main/pygments/formatters/terminal.py +1 -1
  39. data/vendor/pygments-main/pygments/formatters/terminal256.py +1 -1
  40. data/vendor/pygments-main/pygments/lexer.py +76 -12
  41. data/vendor/pygments-main/pygments/lexers/__init__.py +2 -2
  42. data/vendor/pygments-main/pygments/lexers/_asybuiltins.py +1 -1
  43. data/vendor/pygments-main/pygments/lexers/_clbuiltins.py +1 -1
  44. data/vendor/pygments-main/pygments/lexers/_lassobuiltins.py +4 -1
  45. data/vendor/pygments-main/pygments/lexers/_luabuiltins.py +1 -1
  46. data/vendor/pygments-main/pygments/lexers/_mapping.py +26 -10
  47. data/vendor/pygments-main/pygments/lexers/_openedgebuiltins.py +11 -0
  48. data/vendor/pygments-main/pygments/lexers/_phpbuiltins.py +2 -2
  49. data/vendor/pygments-main/pygments/lexers/_postgres_builtins.py +4 -2
  50. data/vendor/pygments-main/pygments/lexers/_robotframeworklexer.py +14 -3
  51. data/vendor/pygments-main/pygments/lexers/_scilab_builtins.py +11 -0
  52. data/vendor/pygments-main/pygments/lexers/_sourcemodbuiltins.py +2 -2
  53. data/vendor/pygments-main/pygments/lexers/_stan_builtins.py +6 -6
  54. data/vendor/pygments-main/pygments/lexers/agile.py +6 -4
  55. data/vendor/pygments-main/pygments/lexers/asm.py +40 -2
  56. data/vendor/pygments-main/pygments/lexers/compiled.py +751 -438
  57. data/vendor/pygments-main/pygments/lexers/dalvik.py +2 -2
  58. data/vendor/pygments-main/pygments/lexers/dotnet.py +1 -1
  59. data/vendor/pygments-main/pygments/lexers/foxpro.py +428 -0
  60. data/vendor/pygments-main/pygments/lexers/functional.py +6 -5
  61. data/vendor/pygments-main/pygments/lexers/hdl.py +3 -3
  62. data/vendor/pygments-main/pygments/lexers/jvm.py +130 -16
  63. data/vendor/pygments-main/pygments/lexers/math.py +250 -9
  64. data/vendor/pygments-main/pygments/lexers/other.py +518 -13
  65. data/vendor/pygments-main/pygments/lexers/parsers.py +3 -2
  66. data/vendor/pygments-main/pygments/lexers/shell.py +48 -2
  67. data/vendor/pygments-main/pygments/lexers/special.py +1 -1
  68. data/vendor/pygments-main/pygments/lexers/sql.py +1 -1
  69. data/vendor/pygments-main/pygments/lexers/templates.py +7 -6
  70. data/vendor/pygments-main/pygments/lexers/text.py +9 -9
  71. data/vendor/pygments-main/pygments/lexers/web.py +264 -51
  72. data/vendor/pygments-main/pygments/plugin.py +1 -1
  73. data/vendor/pygments-main/pygments/scanner.py +1 -1
  74. data/vendor/pygments-main/pygments/style.py +1 -1
  75. data/vendor/pygments-main/pygments/styles/__init__.py +1 -1
  76. data/vendor/pygments-main/pygments/styles/autumn.py +1 -1
  77. data/vendor/pygments-main/pygments/styles/borland.py +1 -1
  78. data/vendor/pygments-main/pygments/styles/bw.py +1 -1
  79. data/vendor/pygments-main/pygments/styles/colorful.py +1 -1
  80. data/vendor/pygments-main/pygments/styles/default.py +1 -1
  81. data/vendor/pygments-main/pygments/styles/emacs.py +1 -1
  82. data/vendor/pygments-main/pygments/styles/friendly.py +1 -1
  83. data/vendor/pygments-main/pygments/styles/fruity.py +1 -1
  84. data/vendor/pygments-main/pygments/styles/manni.py +1 -1
  85. data/vendor/pygments-main/pygments/styles/monokai.py +1 -1
  86. data/vendor/pygments-main/pygments/styles/murphy.py +1 -1
  87. data/vendor/pygments-main/pygments/styles/native.py +1 -1
  88. data/vendor/pygments-main/pygments/styles/pastie.py +1 -1
  89. data/vendor/pygments-main/pygments/styles/perldoc.py +1 -1
  90. data/vendor/pygments-main/pygments/styles/rrt.py +1 -1
  91. data/vendor/pygments-main/pygments/styles/tango.py +1 -1
  92. data/vendor/pygments-main/pygments/styles/trac.py +1 -1
  93. data/vendor/pygments-main/pygments/styles/vim.py +1 -1
  94. data/vendor/pygments-main/pygments/styles/vs.py +1 -1
  95. data/vendor/pygments-main/pygments/token.py +1 -1
  96. data/vendor/pygments-main/pygments/unistring.py +1 -1
  97. data/vendor/pygments-main/pygments/util.py +1 -1
  98. data/vendor/pygments-main/scripts/check_sources.py +2 -2
  99. data/vendor/pygments-main/scripts/detect_missing_analyse_text.py +2 -0
  100. data/vendor/pygments-main/scripts/find_codetags.py +1 -1
  101. data/vendor/pygments-main/scripts/find_error.py +5 -6
  102. data/vendor/pygments-main/setup.cfg +1 -0
  103. data/vendor/pygments-main/setup.py +6 -4
  104. data/vendor/pygments-main/tests/examplefiles/BOM.js +1 -0
  105. data/vendor/pygments-main/tests/examplefiles/autoit_submit.au3 +25 -0
  106. data/vendor/pygments-main/tests/examplefiles/bigtest.nsi +308 -0
  107. data/vendor/pygments-main/tests/examplefiles/ca65_example +284 -0
  108. data/vendor/pygments-main/tests/examplefiles/cbmbas_example +9 -0
  109. data/vendor/pygments-main/tests/examplefiles/classes.dylan +89 -4
  110. data/vendor/pygments-main/tests/examplefiles/example.cob +3556 -0
  111. data/vendor/pygments-main/tests/examplefiles/example.prg +161 -0
  112. data/vendor/pygments-main/tests/examplefiles/example.shell-session +45 -0
  113. data/vendor/pygments-main/tests/examplefiles/example.ts +28 -0
  114. data/vendor/pygments-main/tests/examplefiles/inet_pton6.dg +2 -2
  115. data/vendor/pygments-main/tests/examplefiles/logos_example.xm +28 -0
  116. data/vendor/pygments-main/tests/examplefiles/mg_sample.pro +73 -0
  117. data/vendor/pygments-main/tests/examplefiles/minehunt.qml +112 -0
  118. data/vendor/pygments-main/tests/examplefiles/nanomsg.intr +95 -0
  119. data/vendor/pygments-main/tests/examplefiles/phpMyAdmin.spec +163 -0
  120. data/vendor/pygments-main/tests/examplefiles/rust_example.rs +191 -701
  121. data/vendor/pygments-main/tests/examplefiles/session.dylan-console +9 -0
  122. data/vendor/pygments-main/tests/examplefiles/test.opa +10 -0
  123. data/vendor/pygments-main/tests/examplefiles/test2.pypylog +120 -0
  124. data/vendor/pygments-main/tests/examplefiles/unix-io.lid +37 -0
  125. data/vendor/pygments-main/tests/old_run.py +1 -1
  126. data/vendor/pygments-main/tests/run.py +3 -2
  127. data/vendor/pygments-main/tests/support/tags +36 -0
  128. data/vendor/pygments-main/tests/test_basic_api.py +3 -2
  129. data/vendor/pygments-main/tests/test_clexer.py +1 -1
  130. data/vendor/pygments-main/tests/test_cmdline.py +1 -1
  131. data/vendor/pygments-main/tests/test_examplefiles.py +1 -1
  132. data/vendor/pygments-main/tests/test_html_formatter.py +17 -1
  133. data/vendor/pygments-main/tests/test_latex_formatter.py +1 -1
  134. data/vendor/pygments-main/tests/test_perllexer.py +1 -1
  135. data/vendor/pygments-main/tests/test_regexlexer.py +1 -1
  136. data/vendor/pygments-main/tests/test_token.py +1 -1
  137. data/vendor/pygments-main/tests/test_using_api.py +1 -1
  138. data/vendor/pygments-main/tests/test_util.py +5 -4
  139. metadata +26 -2
@@ -0,0 +1,95 @@
1
+ module: nanomsg
2
+ synopsis: generated bindings for the nanomsg library
3
+ author: Bruce Mitchener, Jr.
4
+ copyright: See LICENSE file in this distribution.
5
+
6
+ define simple-C-mapped-subtype <C-buffer-offset> (<C-char*>)
7
+ export-map <machine-word>, export-function: identity;
8
+ end;
9
+
10
+ define interface
11
+ #include {
12
+ "sp/sp.h",
13
+ "sp/fanin.h",
14
+ "sp/inproc.h",
15
+ "sp/pair.h",
16
+ "sp/reqrep.h",
17
+ "sp/survey.h",
18
+ "sp/fanout.h",
19
+ "sp/ipc.h",
20
+ "sp/pubsub.h",
21
+ "sp/tcp.h"
22
+ },
23
+
24
+ exclude: {
25
+ "SP_HAUSNUMERO",
26
+ "SP_PAIR_ID",
27
+ "SP_PUBSUB_ID",
28
+ "SP_REQREP_ID",
29
+ "SP_FANIN_ID",
30
+ "SP_FANOUT_ID",
31
+ "SP_SURVEY_ID"
32
+ },
33
+
34
+ equate: {"char *" => <c-string>},
35
+
36
+ rename: {
37
+ "sp_recv" => %sp-recv,
38
+ "sp_send" => %sp-send,
39
+ "sp_setsockopt" => %sp-setsockopt
40
+ };
41
+
42
+ function "sp_version",
43
+ output-argument: 1,
44
+ output-argument: 2,
45
+ output-argument: 3;
46
+
47
+ function "sp_send",
48
+ map-argument: { 2 => <C-buffer-offset> };
49
+
50
+ function "sp_recv",
51
+ map-argument: { 2 => <C-buffer-offset> };
52
+
53
+ end interface;
54
+
55
+ // Function for adding the base address of the repeated slots of a <buffer>
56
+ // to an offset and returning the result as a <machine-word>. This is
57
+ // necessary for passing <buffer> contents across the FFI.
58
+
59
+ define function buffer-offset
60
+ (the-buffer :: <buffer>, data-offset :: <integer>)
61
+ => (result-offset :: <machine-word>)
62
+ u%+(data-offset,
63
+ primitive-wrap-machine-word
64
+ (primitive-repeated-slot-as-raw
65
+ (the-buffer, primitive-repeated-slot-offset(the-buffer))))
66
+ end function;
67
+
68
+ define inline function sp-send (socket :: <integer>, data :: <buffer>, flags :: <integer>) => (res :: <integer>)
69
+ %sp-send(socket, buffer-offset(data, 0), data.size, flags)
70
+ end;
71
+
72
+ define inline function sp-recv (socket :: <integer>, data :: <buffer>, flags :: <integer>) => (res :: <integer>)
73
+ %sp-recv(socket, buffer-offset(data, 0), data.size, flags);
74
+ end;
75
+
76
+ define inline method sp-setsockopt (socket :: <integer>, level :: <integer>, option :: <integer>, value :: <integer>)
77
+ with-stack-structure (int :: <C-int*>)
78
+ pointer-value(int) := value;
79
+ let setsockopt-result =
80
+ %sp-setsockopt(socket, level, option, int, size-of(<C-int*>));
81
+ if (setsockopt-result < 0)
82
+ // Check error!
83
+ end;
84
+ setsockopt-result
85
+ end;
86
+ end;
87
+
88
+ define inline method sp-setsockopt (socket :: <integer>, level :: <integer>, option :: <integer>, data :: <byte-string>)
89
+ let setsockopt-result =
90
+ %sp-setsockopt(socket, level, option, as(<c-string>, data), data.size);
91
+ if (setsockopt-result < 0)
92
+ // Check error!
93
+ end;
94
+ setsockopt-result
95
+ end;
@@ -0,0 +1,163 @@
1
+ %define _myadminpath /var/www/myadmin
2
+ %define pkgrelease rc1
3
+ %define microrelease 1
4
+
5
+ Name: phpMyAdmin
6
+ Version: 3.1.1
7
+ Release: %{pkgrelease}.%{microrelease}
8
+ License: GPL
9
+ Group: Applications/Databases/Interfaces
10
+ Source0: http://prdownloads.sourceforge.net/phpmyadmin/%{name}-%{version}-%{pkgrelease}.tar.bz2
11
+ Source1: phpMyAdmin-http.conf
12
+ URL: http://sourceforge.net/projects/phpmyadmin/
13
+ Requires: mysql
14
+ Requires: php-mysql
15
+ Buildarch: noarch
16
+ #BuildRoot: %{_tmppath}/%{name}-root
17
+
18
+ Summary: phpMyAdmin - web-based MySQL administration
19
+
20
+ %description
21
+ phpMyAdmin can manage a whole MySQL-server (needs a super-user) but
22
+ also a single database. To accomplish the latter you'll need a
23
+ properly set up MySQL-user which can read/write only the desired
24
+ database. It's up to you to look up the appropiate part in the MySQL
25
+ manual. Currently phpMyAdmin can:
26
+ - create and drop databases
27
+ - create, copy, drop and alter tables
28
+ - delete, edit and add fields
29
+ - execute any SQL-statement, even batch-queries
30
+ - manage keys on fields
31
+ - load text files into tables
32
+ - create (*) and read dumps of tables
33
+ - export (*) and import data to CSV values
34
+ - administer multiple servers and single databases
35
+ - check referencial integrity
36
+ - create complex queries automatically connecting required tables
37
+ - create PDF graphics of your database layout
38
+ - communicate in more than 38 different languages
39
+
40
+
41
+ %prep
42
+ %setup -q -n %{name}-%{version}-%{pkgrelease}
43
+
44
+
45
+ %build
46
+
47
+
48
+ %install
49
+ [ "${RPM_BUILD_ROOT}" != "/" ] && [ -d "${RPM_BUILD_ROOT}" ] && \
50
+ rm -rf "${RPM_BUILD_ROOT}"
51
+
52
+ # Create directories.
53
+
54
+ install -d "${RPM_BUILD_ROOT}%{_myadminpath}"/{css,js,lang,libraries,themes}
55
+ install -d "${RPM_BUILD_ROOT}%{_myadminpath}"/libraries/{auth,dbg,dbi,engines}
56
+ install -d "${RPM_BUILD_ROOT}%{_myadminpath}"/libraries/{export,tcpdf,import}
57
+ install -d "${RPM_BUILD_ROOT}%{_myadminpath}"/libraries/transformations
58
+ install -d "${RPM_BUILD_ROOT}%{_myadminpath}"/libraries/tcpdf/font
59
+ install -d "${RPM_BUILD_ROOT}%{_myadminpath}"/themes/{darkblue_orange,original}
60
+ install -d "${RPM_BUILD_ROOT}%{_myadminpath}"/themes/darkblue_orange/{css,img}
61
+ install -d "${RPM_BUILD_ROOT}%{_myadminpath}"/themes/original/{css,img}
62
+
63
+ # Install files.
64
+
65
+ install libraries/config.default.php \
66
+ "${RPM_BUILD_ROOT}%{_myadminpath}"/config.inc.php
67
+ install *.{php,ico} "${RPM_BUILD_ROOT}%{_myadminpath}"/
68
+ install ChangeLog LICENSE README "${RPM_BUILD_ROOT}%{_myadminpath}"/
69
+ install Documentation.html docs.css "${RPM_BUILD_ROOT}%{_myadminpath}"/
70
+ install css/* "${RPM_BUILD_ROOT}%{_myadminpath}/css"/
71
+ install js/* "${RPM_BUILD_ROOT}%{_myadminpath}/js"/
72
+ install lang/*.php "${RPM_BUILD_ROOT}%{_myadminpath}/lang"/
73
+ install libraries/*.php "${RPM_BUILD_ROOT}%{_myadminpath}/libraries"/
74
+ install libraries/auth/*.php "${RPM_BUILD_ROOT}%{_myadminpath}/libraries/auth"/
75
+ install libraries/dbg/*.php "${RPM_BUILD_ROOT}%{_myadminpath}/libraries/dbg"/
76
+ install libraries/dbi/*.php "${RPM_BUILD_ROOT}%{_myadminpath}/libraries/dbi"/
77
+ install libraries/engines/*.php \
78
+ "${RPM_BUILD_ROOT}%{_myadminpath}/libraries/engines"/
79
+ install libraries/export/*.php \
80
+ "${RPM_BUILD_ROOT}%{_myadminpath}/libraries/export"/
81
+ install libraries/tcpdf/*.php "${RPM_BUILD_ROOT}%{_myadminpath}/libraries/tcpdf"/
82
+ install libraries/tcpdf/font/*.{php,z} \
83
+ "${RPM_BUILD_ROOT}%{_myadminpath}/libraries/tcpdf/font"/
84
+ install libraries/import/*.php \
85
+ "${RPM_BUILD_ROOT}%{_myadminpath}/libraries/import"/
86
+ install libraries/transformations/*.php \
87
+ "${RPM_BUILD_ROOT}%{_myadminpath}/libraries/transformations"/
88
+ install themes/darkblue_orange/*.{php,png} \
89
+ "${RPM_BUILD_ROOT}%{_myadminpath}/themes/darkblue_orange"/
90
+ install themes/darkblue_orange/css/*.php \
91
+ "${RPM_BUILD_ROOT}%{_myadminpath}/themes/darkblue_orange/css"/
92
+ install themes/darkblue_orange/img/*.{png,ico} \
93
+ "${RPM_BUILD_ROOT}%{_myadminpath}/themes/darkblue_orange/img"/
94
+ install themes/original/*.{php,png} \
95
+ "${RPM_BUILD_ROOT}%{_myadminpath}/themes/original"/
96
+ install themes/original/css/*.php \
97
+ "${RPM_BUILD_ROOT}%{_myadminpath}/themes/original/css"/
98
+ install themes/original/img/*.{png,ico} \
99
+ "${RPM_BUILD_ROOT}%{_myadminpath}/themes/original/img"/
100
+
101
+ # Create documentation directories.
102
+
103
+ DOCROOT="${RPM_BUILD_ROOT}%{_docdir}/%{name}-%{version}"
104
+ install -d "${DOCROOT}"
105
+ install -d "${DOCROOT}"/{lang,scripts,transformations}
106
+
107
+ # Install documentation files.
108
+
109
+ install RELEASE-DATE-* "${DOCROOT}"/
110
+ install CREDITS ChangeLog INSTALL LICENSE "${DOCROOT}"/
111
+ install README TODO "${DOCROOT}"/
112
+ install Documentation.* docs.css "${DOCROOT}"/
113
+ install translators.html "${DOCROOT}"/
114
+ install lang/*.sh "${DOCROOT}"/lang/
115
+ install scripts/* "${DOCROOT}"/scripts/
116
+ install libraries/tcpdf/README "${DOCROOT}"/README.tcpdf
117
+ install libraries/import/README "${DOCROOT}"/README.import
118
+ install libraries/transformations/README "${DOCROOT}"/transformations/
119
+ install libraries/transformations/TEMPLATE* "${DOCROOT}"/transformations/
120
+ install libraries/transformations/*.sh "${DOCROOT}"/transformations/
121
+
122
+ # Install configuration file for Apache.
123
+
124
+ install -d "${RPM_BUILD_ROOT}%{_sysconfdir}/httpd/conf.d"
125
+ install "%{SOURCE1}" \
126
+ "${RPM_BUILD_ROOT}%{_sysconfdir}/httpd/conf.d/phpMyAdmin.conf"
127
+
128
+ # Generate non-configuration file list.
129
+
130
+ (cd "${RPM_BUILD_ROOT}"; ls -d ."%{_myadminpath}"/*) |
131
+ sed -e '/\/config\.inc\.php$/d' -e 's/^.//' > files.list
132
+
133
+
134
+
135
+ %clean
136
+ [ "${RPM_BUILD_ROOT}" != "/" ] && [ -d "${RPM_BUILD_ROOT}" ] && \
137
+ rm -rf "${RPM_BUILD_ROOT}"
138
+
139
+
140
+ %files -f files.list
141
+ %defattr(644, root, root, 755)
142
+ %doc %{_docdir}/%{name}-%{version}
143
+ %dir %{_myadminpath}
144
+ %attr(640,root,apache) %config(noreplace) %verify(not size mtime md5) %{_myadminpath}/config.inc.php
145
+ %config(noreplace) %verify(not size mtime md5) %{_sysconfdir}/httpd/conf.d/*
146
+
147
+
148
+ %changelog
149
+ * Thu Feb 23 2006 Patrick Monnerat <pm@datasphere.ch>
150
+ - Version 2.8.0-rc1.1.
151
+
152
+ * Thu Dec 22 2005 Patrick Monnerat <patrick.monnerat@econophone.ch>
153
+ - Path "nullpw" to allow trying connection with null password after failure.
154
+ - Version 2.7.0-pl1.1.
155
+
156
+ * Mon Aug 22 2005 Patrick Monnerat <patrick.monnerat@econophone.ch>
157
+ - Version 2.6.3-pl1.
158
+
159
+ * Wed Jul 21 2004 Patrick Monnerat <patrick.monnerat@econophone.ch>
160
+ - Version 2.5.7-pl1.
161
+
162
+ * Fri Nov 22 2002 Patrick Monnerat <patrick.monnerat@econophone.ch>
163
+ - Version 2.3.0-rc1.
@@ -1,743 +1,233 @@
1
-
2
- #[doc = "json serialization"];
3
-
4
- import result::{result, ok, err};
5
- import io;
6
- import io::{reader_util, writer_util};
7
- import map;
8
- import map::hashmap;
9
-
10
- export json;
11
- export error;
12
- export to_writer;
13
- export to_str;
14
- export from_reader;
15
- export from_str;
16
- export eq;
17
-
18
- export num;
19
- export string;
20
- export boolean;
21
- export list;
22
- export dict;
23
- export null;
24
-
25
- #[doc = "Represents a json value"]
26
- enum json {
27
- num(float),
28
- string(str),
29
- boolean(bool),
30
- list([json]),
31
- dict(map::hashmap<str,json>),
32
- null,
1
+ // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2
+ // file at the top-level directory of this distribution and at
3
+ // http://rust-lang.org/COPYRIGHT.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6
+ // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7
+ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8
+ // option. This file may not be copied, modified, or distributed
9
+ // except according to those terms.
10
+
11
+ // based on:
12
+ // http://shootout.alioth.debian.org/u32/benchmark.php?test=nbody&lang=java
13
+
14
+ extern mod std;
15
+
16
+ use core::os;
17
+
18
+ // Using sqrt from the standard library is way slower than using libc
19
+ // directly even though std just calls libc, I guess it must be
20
+ // because the the indirection through another dynamic linker
21
+ // stub. Kind of shocking. Might be able to make it faster still with
22
+ // an llvm intrinsic.
23
+ #[nolink]
24
+ extern mod libc {
25
+ #[legacy_exports];
26
+ fn sqrt(n: float) -> float;
33
27
  }
34
28
 
35
- type error = {
36
- line: uint,
37
- col: uint,
38
- msg: str,
39
- };
40
-
41
- #[doc = "Serializes a json value into a io::writer"]
42
- fn to_writer(wr: io::writer, j: json) {
43
- alt j {
44
- num(n) { wr.write_str(float::to_str(n, 6u)); }
45
- string(s) {
46
- wr.write_char('"');
47
- let mut escaped = "";
48
- str::chars_iter(s) { |c|
49
- alt c {
50
- '"' { escaped += "\\\""; }
51
- '\\' { escaped += "\\\\"; }
52
- '\x08' { escaped += "\\b"; }
53
- '\x0c' { escaped += "\\f"; }
54
- '\n' { escaped += "\\n"; }
55
- '\r' { escaped += "\\r"; }
56
- '\t' { escaped += "\\t"; }
57
- _ { escaped += str::from_char(c); }
58
- }
59
- };
60
- wr.write_str(escaped);
61
- wr.write_char('"');
62
- }
63
- boolean(b) {
64
- wr.write_str(if b { "true" } else { "false" });
65
- }
66
- list(v) {
67
- wr.write_char('[');
68
- let mut first = true;
69
- vec::iter(v) { |item|
70
- if !first {
71
- wr.write_str(", ");
72
- }
73
- first = false;
74
- to_writer(wr, item);
75
- };
76
- wr.write_char(']');
77
- }
78
- dict(d) {
79
- if d.size() == 0u {
80
- wr.write_str("{}");
81
- ret;
82
- }
83
-
84
- wr.write_str("{ ");
85
- let mut first = true;
86
- d.items { |key, value|
87
- if !first {
88
- wr.write_str(", ");
89
- }
90
- first = false;
91
- to_writer(wr, string(key));
92
- wr.write_str(": ");
93
- to_writer(wr, value);
94
- };
95
- wr.write_str(" }");
96
- }
97
- null {
98
- wr.write_str("null");
99
- }
100
- }
29
+ fn main() {
30
+ let args = os::args();
31
+ let args = if os::getenv(~"RUST_BENCH").is_some() {
32
+ ~[~"", ~"4000000"]
33
+ } else if args.len() <= 1u {
34
+ ~[~"", ~"100000"]
35
+ } else {
36
+ args
37
+ };
38
+ let n = int::from_str(args[1]).get();
39
+ let mut bodies: ~[Body::props] = NBodySystem::make();
40
+ io::println(fmt!("%f", NBodySystem::energy(bodies)));
41
+ let mut i = 0;
42
+ while i < n {
43
+ NBodySystem::advance(bodies, 0.01);
44
+ i += 1;
45
+ }
46
+ io::println(fmt!("%f", NBodySystem::energy(bodies)));
101
47
  }
102
48
 
103
- #[doc = "Serializes a json value into a string"]
104
- fn to_str(j: json) -> str {
105
- io::with_str_writer { |wr| to_writer(wr, j) }
106
- }
49
+ mod NBodySystem {
50
+ use Body;
107
51
 
108
- type parser = {
109
- rdr: io::reader,
110
- mut ch: char,
111
- mut line: uint,
112
- mut col: uint,
113
- };
52
+ pub fn make() -> ~[Body::props] {
53
+ let mut bodies: ~[Body::props] =
54
+ ~[Body::sun(),
55
+ Body::jupiter(),
56
+ Body::saturn(),
57
+ Body::uranus(),
58
+ Body::neptune()];
114
59
 
115
- impl parser for parser {
116
- fn eof() -> bool { self.ch == -1 as char }
60
+ let mut px = 0.0;
61
+ let mut py = 0.0;
62
+ let mut pz = 0.0;
117
63
 
118
- fn bump() {
119
- self.ch = self.rdr.read_char();
64
+ let mut i = 0;
65
+ while i < 5 {
66
+ px += bodies[i].vx * bodies[i].mass;
67
+ py += bodies[i].vy * bodies[i].mass;
68
+ pz += bodies[i].vz * bodies[i].mass;
120
69
 
121
- if self.ch == '\n' {
122
- self.line += 1u;
123
- self.col = 1u;
124
- } else {
125
- self.col += 1u;
70
+ i += 1;
126
71
  }
127
- }
128
72
 
129
- fn next_char() -> char {
130
- self.bump();
131
- self.ch
132
- }
73
+ // side-effecting
74
+ Body::offset_momentum(&mut bodies[0], px, py, pz);
133
75
 
134
- fn error<T>(msg: str) -> result<T, error> {
135
- err({ line: self.line, col: self.col, msg: msg })
76
+ return bodies;
136
77
  }
137
78
 
138
- fn parse() -> result<json, error> {
139
- alt self.parse_value() {
140
- ok(value) {
141
- // Skip trailing whitespaces.
142
- self.parse_whitespace();
143
- // Make sure there is no trailing characters.
144
- if self.eof() {
145
- ok(value)
146
- } else {
147
- self.error("trailing characters")
79
+ pub fn advance(bodies: &mut [Body::props], dt: float) {
80
+ let mut i = 0;
81
+ while i < 5 {
82
+ let mut j = i + 1;
83
+ while j < 5 {
84
+ advance_one(&mut bodies[i],
85
+ &mut bodies[j], dt);
86
+ j += 1;
148
87
  }
149
- }
150
- e { e }
151
- }
152
- }
153
88
 
154
- fn parse_value() -> result<json, error> {
155
- self.parse_whitespace();
156
-
157
- if self.eof() { ret self.error("EOF while parsing value"); }
158
-
159
- alt self.ch {
160
- 'n' { self.parse_ident("ull", null) }
161
- 't' { self.parse_ident("rue", boolean(true)) }
162
- 'f' { self.parse_ident("alse", boolean(false)) }
163
- '0' to '9' | '-' { self.parse_number() }
164
- '"' {
165
- alt self.parse_str() {
166
- ok(s) { ok(string(s)) }
167
- err(e) { err(e) }
168
- }
169
- }
170
- '[' { self.parse_list() }
171
- '{' { self.parse_object() }
172
- _ { self.error("invalid syntax") }
89
+ i += 1;
173
90
  }
174
- }
175
91
 
176
- fn parse_whitespace() {
177
- while char::is_whitespace(self.ch) { self.bump(); }
178
- }
179
-
180
- fn parse_ident(ident: str, value: json) -> result<json, error> {
181
- if str::all(ident, { |c| c == self.next_char() }) {
182
- self.bump();
183
- ok(value)
184
- } else {
185
- self.error("invalid syntax")
92
+ i = 0;
93
+ while i < 5 {
94
+ move_(&mut bodies[i], dt);
95
+ i += 1;
186
96
  }
187
97
  }
188
98
 
189
- fn parse_number() -> result<json, error> {
190
- let mut neg = 1f;
99
+ pub fn advance_one(bi: &mut Body::props,
100
+ bj: &mut Body::props,
101
+ dt: float) unsafe {
102
+ let dx = bi.x - bj.x;
103
+ let dy = bi.y - bj.y;
104
+ let dz = bi.z - bj.z;
191
105
 
192
- if self.ch == '-' {
193
- self.bump();
194
- neg = -1f;
195
- }
106
+ let dSquared = dx * dx + dy * dy + dz * dz;
196
107
 
197
- let mut res = alt self.parse_integer() {
198
- ok(res) { res }
199
- err(e) { ret err(e); }
200
- };
108
+ let distance = ::libc::sqrt(dSquared);
109
+ let mag = dt / (dSquared * distance);
201
110
 
202
- if self.ch == '.' {
203
- alt self.parse_decimal(res) {
204
- ok(r) { res = r; }
205
- err(e) { ret err(e); }
206
- }
207
- }
208
-
209
- if self.ch == 'e' || self.ch == 'E' {
210
- alt self.parse_exponent(res) {
211
- ok(r) { res = r; }
212
- err(e) { ret err(e); }
213
- }
214
- }
111
+ bi.vx -= dx * bj.mass * mag;
112
+ bi.vy -= dy * bj.mass * mag;
113
+ bi.vz -= dz * bj.mass * mag;
215
114
 
216
- ok(num(neg * res))
115
+ bj.vx += dx * bi.mass * mag;
116
+ bj.vy += dy * bi.mass * mag;
117
+ bj.vz += dz * bi.mass * mag;
217
118
  }
218
119
 
219
- fn parse_integer() -> result<float, error> {
220
- let mut res = 0f;
221
-
222
- alt self.ch {
223
- '0' {
224
- self.bump();
225
-
226
- // There can be only one leading '0'.
227
- alt self.ch {
228
- '0' to '9' { ret self.error("invalid number"); }
229
- _ {}
230
- }
231
- }
232
- '1' to '9' {
233
- while !self.eof() {
234
- alt self.ch {
235
- '0' to '9' {
236
- res *= 10f;
237
- res += ((self.ch as int) - ('0' as int)) as float;
238
-
239
- self.bump();
240
- }
241
- _ { break; }
242
- }
243
- }
244
- }
245
- _ { ret self.error("invalid number"); }
246
- }
247
-
248
- ok(res)
120
+ pub fn move_(b: &mut Body::props, dt: float) {
121
+ b.x += dt * b.vx;
122
+ b.y += dt * b.vy;
123
+ b.z += dt * b.vz;
249
124
  }
250
125
 
251
- fn parse_decimal(res: float) -> result<float, error> {
252
- self.bump();
126
+ pub fn energy(bodies: &[Body::props]) -> float unsafe {
127
+ let mut dx;
128
+ let mut dy;
129
+ let mut dz;
130
+ let mut distance;
131
+ let mut e = 0.0;
253
132
 
254
- // Make sure a digit follows the decimal place.
255
- alt self.ch {
256
- '0' to '9' {}
257
- _ { ret self.error("invalid number"); }
258
- }
259
-
260
- let mut res = res;
261
- let mut dec = 1f;
262
- while !self.eof() {
263
- alt self.ch {
264
- '0' to '9' {
265
- dec /= 10f;
266
- res += (((self.ch as int) - ('0' as int)) as float) * dec;
267
-
268
- self.bump();
269
- }
270
- _ { break; }
271
- }
272
- }
273
-
274
- ok(res)
275
- }
276
-
277
- fn parse_exponent(res: float) -> result<float, error> {
278
- self.bump();
133
+ let mut i = 0;
134
+ while i < 5 {
135
+ e +=
136
+ 0.5 * bodies[i].mass *
137
+ (bodies[i].vx * bodies[i].vx + bodies[i].vy * bodies[i].vy
138
+ + bodies[i].vz * bodies[i].vz);
279
139
 
280
- let mut res = res;
281
- let mut exp = 0u;
282
- let mut neg_exp = false;
140
+ let mut j = i + 1;
141
+ while j < 5 {
142
+ dx = bodies[i].x - bodies[j].x;
143
+ dy = bodies[i].y - bodies[j].y;
144
+ dz = bodies[i].z - bodies[j].z;
283
145
 
284
- alt self.ch {
285
- '+' { self.bump(); }
286
- '-' { self.bump(); neg_exp = true; }
287
- _ {}
288
- }
289
-
290
- // Make sure a digit follows the exponent place.
291
- alt self.ch {
292
- '0' to '9' {}
293
- _ { ret self.error("invalid number"); }
294
- }
295
-
296
- while !self.eof() {
297
- alt self.ch {
298
- '0' to '9' {
299
- exp *= 10u;
300
- exp += (self.ch as uint) - ('0' as uint);
146
+ distance = ::libc::sqrt(dx * dx + dy * dy + dz * dz);
147
+ e -= bodies[i].mass * bodies[j].mass / distance;
301
148
 
302
- self.bump();
303
- }
304
- _ { break; }
149
+ j += 1;
305
150
  }
306
- }
307
151
 
308
- let exp = float::pow_with_uint(10u, exp);
309
- if neg_exp {
310
- res /= exp;
311
- } else {
312
- res *= exp;
152
+ i += 1;
313
153
  }
154
+ return e;
314
155
 
315
- ok(res)
316
- }
317
-
318
- fn parse_str() -> result<str, error> {
319
- let mut escape = false;
320
- let mut res = "";
321
-
322
- while !self.eof() {
323
- self.bump();
324
-
325
- if (escape) {
326
- alt self.ch {
327
- '"' { str::push_char(res, '"'); }
328
- '\\' { str::push_char(res, '\\'); }
329
- '/' { str::push_char(res, '/'); }
330
- 'b' { str::push_char(res, '\x08'); }
331
- 'f' { str::push_char(res, '\x0c'); }
332
- 'n' { str::push_char(res, '\n'); }
333
- 'r' { str::push_char(res, '\r'); }
334
- 't' { str::push_char(res, '\t'); }
335
- 'u' {
336
- // Parse \u1234.
337
- let mut i = 0u;
338
- let mut n = 0u;
339
- while i < 4u {
340
- alt self.next_char() {
341
- '0' to '9' {
342
- n = n * 10u +
343
- (self.ch as uint) - ('0' as uint);
344
- }
345
- _ { ret self.error("invalid \\u escape"); }
346
- }
347
- i += 1u;
348
- }
349
-
350
- // Error out if we didn't parse 4 digits.
351
- if i != 4u {
352
- ret self.error("invalid \\u escape");
353
- }
354
-
355
- str::push_char(res, n as char);
356
- }
357
- _ { ret self.error("invalid escape"); }
358
- }
359
- escape = false;
360
- } else if self.ch == '\\' {
361
- escape = true;
362
- } else {
363
- if self.ch == '"' {
364
- self.bump();
365
- ret ok(res);
366
- }
367
- str::push_char(res, self.ch);
368
- }
369
- }
370
-
371
- self.error("EOF while parsing string")
372
- }
373
-
374
- fn parse_list() -> result<json, error> {
375
- self.bump();
376
- self.parse_whitespace();
377
-
378
- let mut values = [];
379
-
380
- if self.ch == ']' {
381
- self.bump();
382
- ret ok(list(values));
383
- }
384
-
385
- loop {
386
- alt self.parse_value() {
387
- ok(v) { vec::push(values, v); }
388
- e { ret e; }
389
- }
390
-
391
- self.parse_whitespace();
392
- if self.eof() {
393
- ret self.error("EOF while parsing list");
394
- }
395
-
396
- alt self.ch {
397
- ',' { self.bump(); }
398
- ']' { self.bump(); ret ok(list(values)); }
399
- _ { ret self.error("expecting ',' or ']'"); }
400
- }
401
- };
402
- }
403
-
404
- fn parse_object() -> result<json, error> {
405
- self.bump();
406
- self.parse_whitespace();
407
-
408
- let values = map::str_hash();
409
-
410
- if self.ch == '}' {
411
- self.bump();
412
- ret ok(dict(values));
413
- }
414
-
415
- while !self.eof() {
416
- self.parse_whitespace();
417
-
418
- if self.ch != '"' {
419
- ret self.error("key must be a string");
420
- }
421
-
422
- let key = alt self.parse_str() {
423
- ok(key) { key }
424
- err(e) { ret err(e); }
425
- };
426
-
427
- self.parse_whitespace();
428
-
429
- if self.ch != ':' {
430
- if self.eof() { break; }
431
- ret self.error("expecting ':'");
432
- }
433
- self.bump();
434
-
435
- alt self.parse_value() {
436
- ok(value) { values.insert(key, value); }
437
- e { ret e; }
438
- }
439
- self.parse_whitespace();
440
-
441
- alt self.ch {
442
- ',' { self.bump(); }
443
- '}' { self.bump(); ret ok(dict(values)); }
444
- _ {
445
- if self.eof() { break; }
446
- ret self.error("expecting ',' or '}'");
447
- }
448
- }
449
- }
450
-
451
- ret self.error("EOF while parsing object");
452
- }
453
- }
454
-
455
- #[doc = "Deserializes a json value from an io::reader"]
456
- fn from_reader(rdr: io::reader) -> result<json, error> {
457
- let parser = {
458
- rdr: rdr,
459
- mut ch: rdr.read_char(),
460
- mut line: 1u,
461
- mut col: 1u,
462
- };
463
-
464
- parser.parse()
465
- }
466
-
467
- #[doc = "Deserializes a json value from a string"]
468
- fn from_str(s: str) -> result<json, error> {
469
- io::with_str_reader(s, from_reader)
470
- }
471
-
472
- #[doc = "Test if two json values are equal"]
473
- fn eq(value0: json, value1: json) -> bool {
474
- alt (value0, value1) {
475
- (num(f0), num(f1)) { f0 == f1 }
476
- (string(s0), string(s1)) { s0 == s1 }
477
- (boolean(b0), boolean(b1)) { b0 == b1 }
478
- (list(l0), list(l1)) { vec::all2(l0, l1, eq) }
479
- (dict(d0), dict(d1)) {
480
- if d0.size() == d1.size() {
481
- let mut equal = true;
482
- d0.items { |k, v0|
483
- alt d1.find(k) {
484
- some(v1) {
485
- if !eq(v0, v1) { equal = false; } }
486
- none { equal = false; }
487
- }
488
- };
489
- equal
490
- } else {
491
- false
492
- }
493
- }
494
- (null, null) { true }
495
- _ { false }
496
156
  }
497
157
  }
498
158
 
499
- #[cfg(test)]
500
- mod tests {
501
- fn mk_dict(items: [(str, json)]) -> json {
502
- let d = map::str_hash();
503
-
504
- vec::iter(items) { |item|
505
- let (key, value) = item;
506
- d.insert(key, value);
507
- };
508
-
509
- dict(d)
510
- }
511
-
512
- #[test]
513
- fn test_write_null() {
514
- assert to_str(null) == "null";
515
- }
516
-
517
- #[test]
518
- fn test_write_num() {
519
- assert to_str(num(3f)) == "3";
520
- assert to_str(num(3.1f)) == "3.1";
521
- assert to_str(num(-1.5f)) == "-1.5";
522
- assert to_str(num(0.5f)) == "0.5";
523
- }
524
-
525
- #[test]
526
- fn test_write_str() {
527
- assert to_str(string("")) == "\"\"";
528
- assert to_str(string("foo")) == "\"foo\"";
529
- }
530
-
531
- #[test]
532
- fn test_write_bool() {
533
- assert to_str(boolean(true)) == "true";
534
- assert to_str(boolean(false)) == "false";
535
- }
536
-
537
- #[test]
538
- fn test_write_list() {
539
- assert to_str(list([])) == "[]";
540
- assert to_str(list([boolean(true)])) == "[true]";
541
- assert to_str(list([
542
- boolean(false),
543
- null,
544
- list([string("foo\nbar"), num(3.5f)])
545
- ])) == "[false, null, [\"foo\\nbar\", 3.5]]";
546
- }
547
-
548
- #[test]
549
- fn test_write_dict() {
550
- assert to_str(mk_dict([])) == "{}";
551
- assert to_str(mk_dict([("a", boolean(true))])) == "{ \"a\": true }";
552
- assert to_str(mk_dict([
553
- ("a", boolean(true)),
554
- ("b", list([
555
- mk_dict([("c", string("\x0c\r"))]),
556
- mk_dict([("d", string(""))])
557
- ]))
558
- ])) ==
559
- "{ " +
560
- "\"a\": true, " +
561
- "\"b\": [" +
562
- "{ \"c\": \"\\f\\r\" }, " +
563
- "{ \"d\": \"\" }" +
564
- "]" +
565
- " }";
159
+ mod Body {
160
+ use Body;
161
+
162
+ pub const PI: float = 3.141592653589793;
163
+ pub const SOLAR_MASS: float = 39.478417604357432;
164
+ // was 4 * PI * PI originally
165
+ pub const DAYS_PER_YEAR: float = 365.24;
166
+
167
+ pub type props =
168
+ {mut x: float,
169
+ mut y: float,
170
+ mut z: float,
171
+ mut vx: float,
172
+ mut vy: float,
173
+ mut vz: float,
174
+ mass: float};
175
+
176
+ pub fn jupiter() -> Body::props {
177
+ return {mut x: 4.84143144246472090e+00,
178
+ mut y: -1.16032004402742839e+00,
179
+ mut z: -1.03622044471123109e-01,
180
+ mut vx: 1.66007664274403694e-03 * DAYS_PER_YEAR,
181
+ mut vy: 7.69901118419740425e-03 * DAYS_PER_YEAR,
182
+ mut vz: -6.90460016972063023e-05 * DAYS_PER_YEAR,
183
+ mass: 9.54791938424326609e-04 * SOLAR_MASS};
184
+ }
185
+
186
+ pub fn saturn() -> Body::props {
187
+ return {mut x: 8.34336671824457987e+00,
188
+ mut y: 4.12479856412430479e+00,
189
+ mut z: -4.03523417114321381e-01,
190
+ mut vx: -2.76742510726862411e-03 * DAYS_PER_YEAR,
191
+ mut vy: 4.99852801234917238e-03 * DAYS_PER_YEAR,
192
+ mut vz: 2.30417297573763929e-05 * DAYS_PER_YEAR,
193
+ mass: 2.85885980666130812e-04 * SOLAR_MASS};
194
+ }
195
+
196
+ pub fn uranus() -> Body::props {
197
+ return {mut x: 1.28943695621391310e+01,
198
+ mut y: -1.51111514016986312e+01,
199
+ mut z: -2.23307578892655734e-01,
200
+ mut vx: 2.96460137564761618e-03 * DAYS_PER_YEAR,
201
+ mut vy: 2.37847173959480950e-03 * DAYS_PER_YEAR,
202
+ mut vz: -2.96589568540237556e-05 * DAYS_PER_YEAR,
203
+ mass: 4.36624404335156298e-05 * SOLAR_MASS};
204
+ }
205
+
206
+ pub fn neptune() -> Body::props {
207
+ return {mut x: 1.53796971148509165e+01,
208
+ mut y: -2.59193146099879641e+01,
209
+ mut z: 1.79258772950371181e-01,
210
+ mut vx: 2.68067772490389322e-03 * DAYS_PER_YEAR,
211
+ mut vy: 1.62824170038242295e-03 * DAYS_PER_YEAR,
212
+ mut vz: -9.51592254519715870e-05 * DAYS_PER_YEAR,
213
+ mass: 5.15138902046611451e-05 * SOLAR_MASS};
214
+ }
215
+
216
+ pub fn sun() -> Body::props {
217
+ return {mut x: 0.0,
218
+ mut y: 0.0,
219
+ mut z: 0.0,
220
+ mut vx: 0.0,
221
+ mut vy: 0.0,
222
+ mut vz: 0.0,
223
+ mass: SOLAR_MASS};
224
+ }
225
+
226
+ pub fn offset_momentum(props: &mut Body::props,
227
+ px: float, py: float, pz: float) {
228
+ props.vx = -px / SOLAR_MASS;
229
+ props.vy = -py / SOLAR_MASS;
230
+ props.vz = -pz / SOLAR_MASS;
566
231
  }
567
232
 
568
- #[test]
569
- fn test_trailing_characters() {
570
- assert from_str("nulla") ==
571
- err({line: 1u, col: 5u, msg: "trailing characters"});
572
- assert from_str("truea") ==
573
- err({line: 1u, col: 5u, msg: "trailing characters"});
574
- assert from_str("falsea") ==
575
- err({line: 1u, col: 6u, msg: "trailing characters"});
576
- assert from_str("1a") ==
577
- err({line: 1u, col: 2u, msg: "trailing characters"});
578
- assert from_str("[]a") ==
579
- err({line: 1u, col: 3u, msg: "trailing characters"});
580
- assert from_str("{}a") ==
581
- err({line: 1u, col: 3u, msg: "trailing characters"});
582
- }
583
-
584
- #[test]
585
- fn test_read_identifiers() {
586
- assert from_str("n") ==
587
- err({line: 1u, col: 2u, msg: "invalid syntax"});
588
- assert from_str("nul") ==
589
- err({line: 1u, col: 4u, msg: "invalid syntax"});
590
-
591
- assert from_str("t") ==
592
- err({line: 1u, col: 2u, msg: "invalid syntax"});
593
- assert from_str("truz") ==
594
- err({line: 1u, col: 4u, msg: "invalid syntax"});
595
-
596
- assert from_str("f") ==
597
- err({line: 1u, col: 2u, msg: "invalid syntax"});
598
- assert from_str("faz") ==
599
- err({line: 1u, col: 3u, msg: "invalid syntax"});
600
-
601
- assert from_str("null") == ok(null);
602
- assert from_str("true") == ok(boolean(true));
603
- assert from_str("false") == ok(boolean(false));
604
- assert from_str(" null ") == ok(null);
605
- assert from_str(" true ") == ok(boolean(true));
606
- assert from_str(" false ") == ok(boolean(false));
607
- }
608
-
609
- #[test]
610
- fn test_read_num() {
611
- assert from_str("+") ==
612
- err({line: 1u, col: 1u, msg: "invalid syntax"});
613
- assert from_str(".") ==
614
- err({line: 1u, col: 1u, msg: "invalid syntax"});
615
-
616
- assert from_str("-") ==
617
- err({line: 1u, col: 2u, msg: "invalid number"});
618
- assert from_str("00") ==
619
- err({line: 1u, col: 2u, msg: "invalid number"});
620
- assert from_str("1.") ==
621
- err({line: 1u, col: 3u, msg: "invalid number"});
622
- assert from_str("1e") ==
623
- err({line: 1u, col: 3u, msg: "invalid number"});
624
- assert from_str("1e+") ==
625
- err({line: 1u, col: 4u, msg: "invalid number"});
626
-
627
- assert from_str("3") == ok(num(3f));
628
- assert from_str("3.1") == ok(num(3.1f));
629
- assert from_str("-1.2") == ok(num(-1.2f));
630
- assert from_str("0.4") == ok(num(0.4f));
631
- assert from_str("0.4e5") == ok(num(0.4e5f));
632
- assert from_str("0.4e+15") == ok(num(0.4e15f));
633
- assert from_str("0.4e-01") == ok(num(0.4e-01f));
634
- assert from_str(" 3 ") == ok(num(3f));
635
- }
636
-
637
- #[test]
638
- fn test_read_str() {
639
- assert from_str("\"") ==
640
- err({line: 1u, col: 2u, msg: "EOF while parsing string"});
641
- assert from_str("\"lol") ==
642
- err({line: 1u, col: 5u, msg: "EOF while parsing string"});
643
-
644
- assert from_str("\"\"") == ok(string(""));
645
- assert from_str("\"foo\"") == ok(string("foo"));
646
- assert from_str("\"\\\"\"") == ok(string("\""));
647
- assert from_str("\"\\b\"") == ok(string("\x08"));
648
- assert from_str("\"\\n\"") == ok(string("\n"));
649
- assert from_str("\"\\r\"") == ok(string("\r"));
650
- assert from_str("\"\\t\"") == ok(string("\t"));
651
- assert from_str(" \"foo\" ") == ok(string("foo"));
652
- }
653
-
654
- #[test]
655
- fn test_read_list() {
656
- assert from_str("[") ==
657
- err({line: 1u, col: 2u, msg: "EOF while parsing value"});
658
- assert from_str("[1") ==
659
- err({line: 1u, col: 3u, msg: "EOF while parsing list"});
660
- assert from_str("[1,") ==
661
- err({line: 1u, col: 4u, msg: "EOF while parsing value"});
662
- assert from_str("[1,]") ==
663
- err({line: 1u, col: 4u, msg: "invalid syntax"});
664
- assert from_str("[6 7]") ==
665
- err({line: 1u, col: 4u, msg: "expecting ',' or ']'"});
666
-
667
- assert from_str("[]") == ok(list([]));
668
- assert from_str("[ ]") == ok(list([]));
669
- assert from_str("[true]") == ok(list([boolean(true)]));
670
- assert from_str("[ false ]") == ok(list([boolean(false)]));
671
- assert from_str("[null]") == ok(list([null]));
672
- assert from_str("[3, 1]") == ok(list([num(3f), num(1f)]));
673
- assert from_str("\n[3, 2]\n") == ok(list([num(3f), num(2f)]));
674
- assert from_str("[2, [4, 1]]") ==
675
- ok(list([num(2f), list([num(4f), num(1f)])]));
676
- }
677
-
678
- #[test]
679
- fn test_read_dict() {
680
- assert from_str("{") ==
681
- err({line: 1u, col: 2u, msg: "EOF while parsing object"});
682
- assert from_str("{ ") ==
683
- err({line: 1u, col: 3u, msg: "EOF while parsing object"});
684
- assert from_str("{1") ==
685
- err({line: 1u, col: 2u, msg: "key must be a string"});
686
- assert from_str("{ \"a\"") ==
687
- err({line: 1u, col: 6u, msg: "EOF while parsing object"});
688
- assert from_str("{\"a\"") ==
689
- err({line: 1u, col: 5u, msg: "EOF while parsing object"});
690
- assert from_str("{\"a\" ") ==
691
- err({line: 1u, col: 6u, msg: "EOF while parsing object"});
692
-
693
- assert from_str("{\"a\" 1") ==
694
- err({line: 1u, col: 6u, msg: "expecting ':'"});
695
- assert from_str("{\"a\":") ==
696
- err({line: 1u, col: 6u, msg: "EOF while parsing value"});
697
- assert from_str("{\"a\":1") ==
698
- err({line: 1u, col: 7u, msg: "EOF while parsing object"});
699
- assert from_str("{\"a\":1 1") ==
700
- err({line: 1u, col: 8u, msg: "expecting ',' or '}'"});
701
- assert from_str("{\"a\":1,") ==
702
- err({line: 1u, col: 8u, msg: "EOF while parsing object"});
703
-
704
- assert eq(result::get(from_str("{}")), mk_dict([]));
705
- assert eq(result::get(from_str("{\"a\": 3}")),
706
- mk_dict([("a", num(3.0f))]));
707
-
708
- assert eq(result::get(from_str("{ \"a\": null, \"b\" : true }")),
709
- mk_dict([("a", null), ("b", boolean(true))]));
710
- assert eq(result::get(from_str("\n{ \"a\": null, \"b\" : true }\n")),
711
- mk_dict([("a", null), ("b", boolean(true))]));
712
- assert eq(result::get(from_str("{\"a\" : 1.0 ,\"b\": [ true ]}")),
713
- mk_dict([
714
- ("a", num(1.0)),
715
- ("b", list([boolean(true)]))
716
- ]));
717
- assert eq(result::get(from_str(
718
- "{" +
719
- "\"a\": 1.0, " +
720
- "\"b\": [" +
721
- "true," +
722
- "\"foo\\nbar\", " +
723
- "{ \"c\": {\"d\": null} } " +
724
- "]" +
725
- "}")),
726
- mk_dict([
727
- ("a", num(1.0f)),
728
- ("b", list([
729
- boolean(true),
730
- string("foo\nbar"),
731
- mk_dict([
732
- ("c", mk_dict([("d", null)]))
733
- ])
734
- ]))
735
- ]));
736
- }
737
-
738
- #[test]
739
- fn test_multiline_errors() {
740
- assert from_str("{\n \"foo\":\n \"bar\"") ==
741
- err({line: 3u, col: 8u, msg: "EOF while parsing object"});
742
- }
743
233
  }