Skip to content

Commit

Permalink
Add input() built-in function
Browse files Browse the repository at this point in the history
  • Loading branch information
arshajii committed Aug 5, 2024
1 parent 36167bf commit 5e2d041
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/intro/releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Upgraded to LLVM 17 (from 15).
- Updates to several existing functions, such as adding `key` and
`default` arguments to `min()` and `max()`.
- Slice arguments can now be of any type, not just `int`.
- Added `input()` function.

## Other improvements

Expand Down
22 changes: 22 additions & 0 deletions stdlib/internal/builtin.codon
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,28 @@ def print(*args, sep: str = " ", end: str = "\n", file=_stdout, flush: bool = Fa
if flush:
_C.fflush(fp)

def input(prompt: str = ""):
stdout = _C.seq_stdout()
stderr = _C.seq_stderr()
stdin = _C.seq_stdin()
_C.fflush(stderr)
_C.fflush(stdout)
print(prompt, end="")
buf = cobj()
n = 0
s = _C.getline(__ptr__(buf), __ptr__(n), stdin)
if s > 0:
if buf[s - 1] == byte(10):
s -= 1 # skip trailing '\n'
if s != 0 and buf[s - 1] == byte(13):
s -= 1 # skip trailing '\r'
ans = str(buf, s).__ptrcopy__()
_C.free(buf)
return ans
else:
_C.free(buf)
raise EOFError("EOF when reading a line")

@extend
class __internal__:
def print(*args):
Expand Down
7 changes: 7 additions & 0 deletions stdlib/internal/python.codon
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ PyExc_RuntimeError = cobj()
PyExc_NotImplementedError = cobj()
PyExc_StopIteration = cobj()
PyExc_AssertionError = cobj()
PyExc_EOFError = cobj()
PyExc_SystemExit = cobj()

_PY_MODULE_CACHE = Dict[str, pyobj]()
Expand Down Expand Up @@ -327,6 +328,7 @@ def init_handles_dlopen(py_handle: cobj):
global PyExc_NotImplementedError
global PyExc_StopIteration
global PyExc_AssertionError
global PyExc_EOFError
global PyExc_SystemExit

Py_DecRef = dlsym(py_handle, "Py_DecRef")
Expand Down Expand Up @@ -460,6 +462,7 @@ def init_handles_dlopen(py_handle: cobj):
PyExc_NotImplementedError = Ptr[cobj](dlsym(py_handle, "PyExc_NotImplementedError", cobj))[0]
PyExc_StopIteration = Ptr[cobj](dlsym(py_handle, "PyExc_StopIteration", cobj))[0]
PyExc_AssertionError = Ptr[cobj](dlsym(py_handle, "PyExc_AssertionError", cobj))[0]
PyExc_EOFError = Ptr[cobj](dlsym(py_handle, "PyExc_EOFError", cobj))[0]
PyExc_SystemExit = Ptr[cobj](dlsym(py_handle, "PyExc_SystemExit", cobj))[0]

def init_handles_static():
Expand Down Expand Up @@ -594,6 +597,7 @@ def init_handles_static():
from C import PyExc_NotImplementedError: cobj as _PyExc_NotImplementedError
from C import PyExc_StopIteration: cobj as _PyExc_StopIteration
from C import PyExc_AssertionError: cobj as _PyExc_AssertionError
from C import PyExc_EOFError: cobj as _PyExc_EOFError
from C import PyExc_SystemExit: cobj as _PyExc_SystemExit

global Py_DecRef
Expand Down Expand Up @@ -727,6 +731,7 @@ def init_handles_static():
global PyExc_NotImplementedError
global PyExc_StopIteration
global PyExc_AssertionError
global PyExc_EOFError
global PyExc_SystemExit

Py_DecRef = _Py_DecRef
Expand Down Expand Up @@ -860,6 +865,7 @@ def init_handles_static():
PyExc_NotImplementedError = _PyExc_NotImplementedError
PyExc_StopIteration = _PyExc_StopIteration
PyExc_AssertionError = _PyExc_AssertionError
PyExc_EOFError = _PyExc_EOFError
PyExc_SystemExit = _PyExc_SystemExit

def init_error_py_types():
Expand All @@ -881,6 +887,7 @@ def init_error_py_types():
NotImplementedError._pytype = PyExc_NotImplementedError
StopIteration._pytype = PyExc_StopIteration
AssertionError._pytype = PyExc_AssertionError
EOFError._pytype = PyExc_EOFError
SystemExit._pytype = PyExc_SystemExit

def setup_python(python_loaded: bool):
Expand Down
6 changes: 6 additions & 0 deletions stdlib/internal/types/error.codon
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ class AssertionError(Static[Exception]):
super().__init__("AssertionError", message)
self.python_type = self.__class__._pytype

class EOFError(Static[Exception]):
_pytype: ClassVar[cobj] = cobj()
def __init__(self, message: str = ""):
super().__init__("EOFError", message)
self.python_type = self.__class__._pytype

class SystemExit(Static[BaseException]):
_pytype: ClassVar[cobj] = cobj()
_status: int
Expand Down
7 changes: 7 additions & 0 deletions test/app/input.codon
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
print(input("input: "), end=',')
print(input(), end=',')
print(input(), end=',')
try:
input()
except EOFError:
print('X')
3 changes: 3 additions & 0 deletions test/app/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
aa bb

cc
3 changes: 3 additions & 0 deletions test/app/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ gcc "$testdir/test.c" -L"$arg" -Wl,-rpath,"$arg" -lcodon_export_test -o "$arg/te

# exit code test
$codon run "$testdir/exit.codon" || if [[ $? -ne 42 ]]; then exit 4; fi

# input test
[ "$($codon run "$testdir/input.codon" < "$testdir/input.txt")" == "input: aa bb,,cc,X" ] || exit 5

0 comments on commit 5e2d041

Please sign in to comment.