pygments.rb 0.3.7 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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
  }