-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathio.jou
More file actions
201 lines (183 loc) · 6.41 KB
/
io.jou
File metadata and controls
201 lines (183 loc) · 6.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# IO = Input and Output: reading/writing files, printing to terminal,
# reading keyboard input.
import "stdlib/intnative.jou"
# Printing to terminal (stdout)
#
# You can usually ignore the return values of these functions.
# If you are paranoid about error handling, you can use them to
# check whether printing failed.
#
# See also printf() manual page: https://linux.die.net/man/3/printf
@public
declare putchar(a_byte: int) -> int # Print a byte (parameter type is "int" for historical reasons)
@public
declare puts(string: byte*) -> int # Print a string followed by "\n"
@public
declare printf(pattern: byte*, ...) -> int # Example: printf("%s %d\n", "hi", 123)
@public
const EOF: int = -1
# Reads one character of keyboard input (stdin).
#
# Return value is either a valid byte (use 'as byte') or EOF. If EOF is
# returned, it means either end of file or reading error. You can use
# ferror(get_stdin()) to determine whether there was an error.
#
# See fgets() if you want to read a line.
@public
declare getchar() -> int
# Parsing input. For example, this expects the user to type two
# numbers separated by a comma:
#
# x: int
# y: int
# printf("Enter coordinates: ")
# scanf("%d,%d\n", &x, &y)
#
# Return value indicates how many elements were matched. In the
# example above, return value 2 means success.
#
# See also scanf() manual page: https://linux.die.net/man/3/scanf
@public
declare scanf(pattern: byte*, ...) -> int # Parse keyboard input (stdin)
@public
class FILE:
# The members that are actually inside this class are
# platform-specific. Use the functions below instead of trying
# to accessing the members directly.
pass
# The special files stdin, stdout and stderr are very platform-specific. In C,
# if you use the global variable `stdin`, it may actually be a macro, which
# means that the compiler replaces your simple `stdin` with something more
# complicated, like `(__acrt_iob_func(0))` on Windows.
#
# To be explicit, instead of global variables like `stdin`, Jou gives you
# functions like `get_stdin()` to access the streams.
#
# Example:
#
# fprintf(get_stderr(), "Warning: blah blah\n")
#
if WINDOWS:
declare __acrt_iob_func(index: int) -> FILE*
elif MACOS:
declare global __stdinp: FILE*
declare global __stdoutp: FILE*
declare global __stderrp: FILE*
elif LINUX:
declare global stdin: FILE*
declare global stdout: FILE*
declare global stderr: FILE*
elif NETBSD:
if IS_32BIT:
declare global __sF: byte[88][3] # sizeof(FILE) == 88
else:
declare global __sF: byte[152][3] # sizeof(FILE) == 152
else:
assert False # unsupported system
# Returns stdin, the special file for reading keyboard input from terminal.
@public
def get_stdin() -> FILE*:
if WINDOWS:
return __acrt_iob_func(0)
elif MACOS:
return __stdinp
elif LINUX:
return stdin
elif NETBSD:
return &__sF[0] as FILE*
else:
assert False
# Returns stdout, the special file for printing to terminal.
@public
def get_stdout() -> FILE*:
if WINDOWS:
return __acrt_iob_func(1)
elif MACOS:
return __stdoutp
elif LINUX:
return stdout
elif NETBSD:
return &__sF[1] as FILE*
else:
assert False
# Returns stderr, the special file for showing error and warning messages.
#
# By default, stdout and stderr both appear on the terminal, but it is possible
# to separate the two. For example, redirecting to file by adding `> file.txt`
# at the end of a command only redirects stdout. This is intended to be used so
# that you print the program's normal output to stdout and error/warning
# messages to stderr.
@public
def get_stderr() -> FILE*:
if WINDOWS:
return __acrt_iob_func(2)
elif MACOS:
return __stderrp
elif LINUX:
return stderr
elif NETBSD:
return &__sF[2] as FILE*
else:
assert False
# Open/close a file for reading or writing. Mode can be e.g. "r", "w",
# "a", "rb", "wb" or "ab". The meanings of these modes are as in many
# other languages, such as Python.
#
# The "b" at the end of the mode makes a difference only on Windows.
# Text files on Windows typically use two bytes "\r\n" for newlines,
# even though Jou code typically uses "\n". Without "b", the file will
# convert between "\n" and "\r\n" automatically.
@public
declare fopen(path: byte*, mode: byte*) -> FILE*
@public
declare fclose(file: FILE*) -> int # Call this when done with the file. Return value is not meaningful.
# Similar to other functions, but these read/write a file.
@public
declare fputc(a_byte: int, file: FILE*) -> int # see putchar()
@public
declare fputs(string: byte*, file: FILE*) -> int # does NOT add '\n' like puts() does
@public
declare fprintf(file: FILE *, pattern: byte*, ...) -> int
@public
declare fgetc(file: FILE*) -> int # see getchar()
@public
declare fscanf(file: FILE*, pattern: byte*, ...) -> int
# Reads at most n items of data, each of size "itemsize". Returns number of items read.
# Usually this is used with itemsize 1, so return value is number of bytes.
@public
declare fread(destination: byte*, itemsize: intnative, n: intnative, file: FILE*) -> intnative
# Writes n items of data, each of size "itemsize". Returns number of items successfully written.
# Usually this is used with itemsize 1, so return value is number of bytes.
@public
declare fwrite(data: byte*, itemsize: intnative, n: intnative, file: FILE*) -> intnative
# Ensure that output is actually written. It may remain buffered
# if this function isn't called.
@public
declare fflush(file: FILE*) -> int
# Read a line of text from file into a string starting at the given
# pointer. Reading stops at newline character, end of file, on error,
# or when the resulting string (including newline and '\0') wouldn't
# fit within n bytes.
#
# Return value: NULL on error, same as destination on success.
#
# For example, to read a line of text from stdin (user typing on keyboard)
# similarly to input() in Python:
#
# line: byte[1000]
# if fgets(line, sizeof(line), get_stdin()) == NULL:
# printf("Failed to read input\n")
# else:
# if ends_with(line, "\n"):
# line[strlen(line) - 1] = '\0'
# printf("Got %s\n", line)
@public
declare fgets(destination: byte*, n: int, file: FILE*) -> byte*
# TODO: document
@public
declare feof(file: FILE*) -> int
@public
declare ferror(file: FILE*) -> int
# Move back to beginning of file.
@public
declare rewind(file: FILE*) -> None