-
Notifications
You must be signed in to change notification settings - Fork 642
Implementation of raw_input() #233
Changes from 2 commits
eabe6eb
bdfc7c6
d9ff589
075532a
a096994
7d1f71a
46ed7a3
f385580
6a2d03c
46f6e5f
6b2dab8
1a8f9da
347b496
8e2d7fd
9abd463
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ | |
package grumpy | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"math/big" | ||
"os" | ||
|
@@ -559,6 +560,42 @@ func builtinRange(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) | |
return ListType.Call(f, []*Object{r}, nil) | ||
} | ||
|
||
func builtinRawInput(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) { | ||
if len(args) > 1 { | ||
msg := fmt.Sprintf("[raw_]input expcted at most 1 arguments, got %d", len(args)) | ||
return nil, f.RaiseType(TypeErrorType, msg) | ||
} | ||
|
||
fin := os.Stdin | ||
fout := os.Stdout | ||
if fin == nil { | ||
msg := fmt.Sprintf("[raw_]input: lost sys.stdin") | ||
return nil, f.RaiseType(RuntimeErrorType, msg) | ||
} | ||
|
||
if fout == nil { | ||
msg := fmt.Sprintf("[raw_]input: lost sys.stdout") | ||
return nil, f.RaiseType(RuntimeErrorType, msg) | ||
} | ||
|
||
in := bufio.NewReader(fin) | ||
if len(args) == 1 { | ||
prompt, _ := ToStr(f, args[0]) | ||
fmt.Fprint(fout, prompt.Value()) | ||
} | ||
s, _, _ := in.ReadLine() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ReadLine() isn't ideal here because it can return with less than a full line. I think the right thing to do is probably use the grumpy.File object representing sys.stdin and call readLine() on it. But there's no clear way to get the sys module from here. One possible solution that would be to create Stdin, Stdout and Stderr variables in the grumpy package that wrap os.Stdin/out/err with a grumpy.File object, and then have the sys module expose those instead of creating new files. The grumpy.Print() function could then use the new Stdout object. This isn't perfect but I think it is an improvement over what we have today. |
||
|
||
// Todo: Should implement more cases of error. | ||
pySsizeTmax := ((^uint(0)) - 1) >> 1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that if len(s) were ever > than this value that Go would panic so don't bother checking this. |
||
size := len(s) | ||
if uint(size) > pySsizeTmax { | ||
msg := fmt.Sprintf("[raw_]input: input too long") | ||
return nil, f.RaiseType(OverflowErrorType, msg) | ||
} | ||
|
||
return NewStr(string(s[0:size])).ToObject(), nil | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How is this different than |
||
} | ||
|
||
func builtinRepr(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) { | ||
if raised := checkFunctionArgs(f, "repr", args, ObjectType); raised != nil { | ||
return nil, raised | ||
|
@@ -666,6 +703,7 @@ func init() { | |
"ord": newBuiltinFunction("ord", builtinOrd).ToObject(), | ||
"print": newBuiltinFunction("print", builtinPrint).ToObject(), | ||
"range": newBuiltinFunction("range", builtinRange).ToObject(), | ||
"raw_input": newBuiltinFunction("raw_input", builtinRawInput).ToObject(), | ||
"repr": newBuiltinFunction("repr", builtinRepr).ToObject(), | ||
"setattr": newBuiltinFunction("setattr", builtinSetAttr).ToObject(), | ||
"sorted": newBuiltinFunction("sorted", builtinSorted).ToObject(), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than writing to Stdout directly, you could use the Print() function:
Print(f, args, false)