Skip to content

Commit 89dc92c

Browse files
committed
Page 0.28.0
- Type unions are no longer stored as sets - Renamed src/std/testing.nps to src/std/testing.pg - Added the 'os' builtin library with the 'stderr', 'stdout', and 'stdin' symbols - Added the 'io' builtin library with the 'f-write', 'f-open', 'f-close', and 'f-read' operators - Added the ExtItem datatype, which represents a pointer to abstract data
1 parent f2a564b commit 89dc92c

9 files changed

Lines changed: 304 additions & 112 deletions

File tree

page.nimble

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Package
22

3-
version = "0.27.1"
3+
version = "0.28.0"
44
author = "Nuclear Pasta"
55
description = "A PostScript-like language"
66
license = "Apache-2.0"

src/builtinlibs/libhttp.nim

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ addF("init", """
3030
'init'
3131
UA R ->
3232
Initializes the HTTP client with the useragent UA and maximum redirects R.
33-
""", @[("UA", t tString), ("R", t tInteger)]):
33+
""", @[("UA", tString), ("R", tInteger)]):
3434
let
3535
redirects = s.pop().intv
3636
useragent = s.pop().strv
@@ -42,7 +42,7 @@ addF("req", """
4242
U B T -> R
4343
Sends a request of a specified type T with a body B to a url U,
4444
then returns a response R.
45-
""", @[("U", t tString), ("B", t tString), ("T", t tSymbol)]):
45+
""", @[("U", tString), ("B", tString), ("T", tSymbol)]):
4646
checkClient()
4747

4848
let
@@ -72,26 +72,26 @@ addS("get", """
7272
'get'
7373
U -> R
7474
Sends a GET request to a URL U.
75-
""", @[("U", t tString)]):
75+
""", @[("U", tString)]):
7676
"() /GET req"
7777

7878
addS("post", """
7979
'post'
8080
U B -> R
8181
Sends a POST request to a URL U with a body B.
82-
""", @[("U", t tString)]):
82+
""", @[("U", tString)]):
8383
"/POST req"
8484

8585
addS("put", """
8686
'put'
8787
U B -> R
8888
Sends a PUT request to a URL U with a body B.
89-
""", @[("U", t tString)]):
89+
""", @[("U", tString)]):
9090
"/POST req"
9191

9292
addS("delete", """
9393
'delete'
9494
U -> R
9595
Sends a DELETE request to a URL U.
96-
""", @[("U", t tString)]):
96+
""", @[("U", tString)]):
9797
"() /DELETE req"

src/builtinlibs/libio.nim

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import std/[
2+
strutils,
3+
strformat,
4+
os
5+
]
6+
7+
import common
8+
9+
10+
let lib* = newDict(0)
11+
12+
template addV(name, doc: string, item: Value) =
13+
addV(lib, name, doc, item)
14+
15+
template addF(name, doc: string, args: ProcArgs, body: untyped) =
16+
addF(lib, name, doc, args, body)
17+
18+
template addS(name, doc: string, args: ProcArgs, body: string) =
19+
addS(lib, "io.pg", name, doc, args, body)
20+
21+
22+
func newPgFile*(f: File, path: string): Value =
23+
result = newExtitem(cast[pointer](f))
24+
25+
let fname = fmt"File object at '{path}'"
26+
27+
result.id = "File"
28+
result.fmtf = func(_: pointer): string = fname
29+
30+
31+
addF("f-open",
32+
"""
33+
'f-open'
34+
P M -> F
35+
Opens a filepath P with the specified mode symbol M and returns its file object F.
36+
The valid modes are:
37+
- /r (read); opens the file for reading, throws an error if the file doesn't exist.
38+
- /w (write); opens the file for writing, throws an error if the file doesn't exist.
39+
- /rw (readwrite); opens the file for reading and writing, throws an error if the file doesn't exist.
40+
- /a (append); opens the file for writing and appends to the end of the file when written to, throws an error if the file doesn't exist.
41+
- /c (create); opens the file for reading and writing, creates the file if it doesn't exist.
42+
""", @[("P", tString), ("M", tSymbol)]):
43+
let
44+
modeName = s.pop().strv
45+
path = s.pop().strv
46+
47+
var
48+
mode: FileMode
49+
f: File
50+
51+
case modeName
52+
of "r":
53+
mode = fmRead
54+
of "w":
55+
mode = fmWrite
56+
else:
57+
raise newPgError(fmt"Invalid file mode '{modeName}'")
58+
59+
if not path.fileExists() and mode != fmReadWrite:
60+
raise newPgError(fmt"File '{path}' does not exist")
61+
62+
if not f.open(path, mode):
63+
raise newPgError(fmt"File '{path}' could not be opened")
64+
65+
s.push(f.newPgFile(path.absolutePath()))
66+
67+
addF("f-close",
68+
"""
69+
'f-close'
70+
F ->
71+
Closes a file object F.
72+
Trying to use a file object after it was closed is undefined behavior.
73+
""", @[("F", tExtitem)]):
74+
let fobj = s.pop()
75+
76+
if fobj isnot "File":
77+
raise newPgError("Given object is not a File object")
78+
79+
let f = cast[File](fobj.dat)
80+
81+
f.close()
82+
83+
addF("f-read",
84+
"""
85+
'f-readall'
86+
F -> S
87+
Reads everything from a file object F and returns the contents S.
88+
""", @[("F", tExtitem)]):
89+
let fobj = s.pop()
90+
91+
if fobj isnot "File":
92+
raise newPgError("Given object is not a File object")
93+
94+
let f = cast[File](fobj.dat)
95+
96+
var content: string
97+
98+
try:
99+
content = f.readAll()
100+
except IoError as e:
101+
raise newPgError(e.msg)
102+
103+
s.push(newString(content))
104+
105+
addF("f-write",
106+
"""
107+
'f-write'
108+
F S -> WS
109+
Writes a string S to a file object F and returns the amount written WS.
110+
""", @[("F", tExtitem), ("S", tString)]):
111+
let
112+
str = s.pop().strv
113+
fobj = s.pop()
114+
115+
if fobj isnot "File":
116+
raise newPgError("Given object is not a File object")
117+
118+
let f = cast[File](fobj.dat)
119+
120+
try:
121+
f.write(str)
122+
except IoError as e:
123+
raise newPgError(e.msg)

src/builtinlibs/libos.nim

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import
2+
common,
3+
libio
4+
5+
6+
let lib* = newDict(0)
7+
8+
template addV(name, doc: string, item: Value) =
9+
addV(lib, name, doc, item)
10+
11+
template addF(name, doc: string, args: ProcArgs, body: untyped) =
12+
addF(lib, name, doc, args, body)
13+
14+
template addS(name, doc: string, args: ProcArgs, body: string) =
15+
addS(lib, "os.pg", name, doc, args, body)
16+
17+
18+
let
19+
pgStdin* = stdin.newPgFile("stdin")
20+
pgStdout* = stdin.newPgFile("stdout")
21+
pgStderr* = stdin.newPgFile("stderr")
22+
23+
24+
addV("stdin",
25+
"""
26+
'stdin'
27+
-> F
28+
Returns the file object for STDIN.
29+
"""):
30+
pgStdin
31+
32+
addV("stdout",
33+
"""
34+
'stdout'
35+
-> F
36+
Returns the file object for STDOUT.
37+
"""):
38+
pgStdout
39+
40+
addV("stderr",
41+
"""
42+
'stderr'
43+
-> F
44+
Returns the file object for STDERR.
45+
"""):
46+
pgStderr

src/builtinlibs/libstrings.nim

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ addF("chars",
2323
'chars'
2424
S -> L
2525
Separates a string S into a list L of character strings.
26-
""", @[("S", t tString)]):
26+
""", @[("S", tString)]):
2727
let str = s.pop().strv
2828

2929
var chars = newSeq[Value](str.len)
@@ -38,7 +38,7 @@ addF("split",
3838
'split'
3939
S D -> L
4040
Separates a string S into a list L of parts by a delimiter D.
41-
""", @[("S", t tString), ("D", t tString)]):
41+
""", @[("S", tString), ("D", tString)]):
4242
let
4343
delim = s.pop().strv
4444
str = s.pop().strv
@@ -55,7 +55,7 @@ addF("replace",
5555
'replace'
5656
S Old New -> S'
5757
Replaces all occurences of Old with New in a string S.
58-
""", @[("S", t tString), ("Old", t tString), ("New", t tString)]):
58+
""", @[("S", tString), ("Old", tString), ("New", tString)]):
5959
let
6060
new = s.pop().strv
6161
old = s.pop().strv
@@ -68,7 +68,7 @@ addF("joins",
6868
'joins'
6969
L D -> S
7070
Combines a list of strings L into a single string S, separated by delimiter D.
71-
""", @[("L", t tList), ("D", t tString)]):
71+
""", @[("L", tList), ("D", tString)]):
7272
let
7373
delim = s.pop().strv
7474
l = s.pop().listv
@@ -87,14 +87,14 @@ addS("join",
8787
"""
8888
L -> S
8989
Joins a list of strings end to end.
90-
""", @[("L", t tList)]):
90+
""", @[("L", tList)]):
9191
"() joins"
9292

9393
addF("lower",
9494
"""
9595
S -> S'
9696
Sets all the ASCII letters of a string S to lowercase and returns the resulting string S'.
97-
""", @[("S", t tString)]):
97+
""", @[("S", tString)]):
9898
let str = s.pop().strv
9999

100100
s.push(newString(str.toLowerAscii()))
@@ -103,7 +103,7 @@ addF("upper",
103103
"""
104104
S -> S'
105105
Sets all the ASCII letters of a string S to uppercase and returns the resulting string S'.
106-
""", @[("S", t tString)]):
106+
""", @[("S", tString)]):
107107
let str = s.pop().strv
108108

109109
s.push(newString(str.toUpperAscii()))

0 commit comments

Comments
 (0)