@@ -46,15 +46,33 @@ type yyLex struct {
46
46
parenthesis int // number of open ( )
47
47
brace int // number of open { }
48
48
mod ast.Mod // output
49
+ startToken int // initial token to output
49
50
}
50
51
51
- func NewLex (r io.Reader ) * yyLex {
52
+ // Create a new lexer
53
+ //
54
+ // The mode argument specifies what kind of code must be compiled; it
55
+ // can be 'exec' if source consists of a sequence of statements,
56
+ // 'eval' if it consists of a single expression, or 'single' if it
57
+ // consists of a single interactive statement
58
+ func NewLex (r io.Reader , mode string ) (* yyLex , error ) {
52
59
x := & yyLex {
53
60
reader : bufio .NewReader (r ),
54
61
indentStack : []int {0 },
55
62
state : readString ,
56
63
}
57
- return x
64
+ switch mode {
65
+ case "exec" :
66
+ x .startToken = FILE_INPUT
67
+ case "eval" :
68
+ x .startToken = EVAL_INPUT
69
+ case "single" :
70
+ x .startToken = SINGLE_INPUT
71
+ x .interactive = true
72
+ default :
73
+ return nil , py .ExceptionNewf (py .ValueError , "compile mode must be 'exec', 'eval' or 'single'" )
74
+ }
75
+ return x , nil
58
76
}
59
77
60
78
// Refill line
@@ -222,6 +240,9 @@ func init() {
222
240
tokenToString [DEDENT ] = "DEDENT"
223
241
tokenToString [STRING ] = "STRING"
224
242
tokenToString [NUMBER ] = "NUMBER"
243
+ tokenToString [FILE_INPUT ] = "FILE_INPUT"
244
+ tokenToString [SINGLE_INPUT ] = "SINGLE_INPUT"
245
+ tokenToString [EVAL_INPUT ] = "EVAL_INPUT"
225
246
}
226
247
227
248
// True if there are any open brackets
@@ -309,6 +330,13 @@ func (x *yyLex) Lex(yylval *yySymType) (ret int) {
309
330
defer func () { fmt .Printf ("LEX> %v\n " , newLexToken (ret , yylval )) }()
310
331
}
311
332
333
+ // Return initial token
334
+ if x .startToken != eof {
335
+ token := x .startToken
336
+ x .startToken = eof
337
+ return token
338
+ }
339
+
312
340
// FIXME keep x.pos up to date
313
341
x .pos .Lineno = 42
314
342
x .pos .ColOffset = 43
@@ -318,13 +346,14 @@ func (x *yyLex) Lex(yylval *yySymType) (ret int) {
318
346
// Read x.line
319
347
x .refill ()
320
348
x .state ++
321
- // an empty line while reading interactive input should return a NEWLINE
322
- if x .interactive && (x .line == "" || x .line == "\n " ) {
349
+ if x .line == "" && x .eof {
350
+ x .state = checkEof
351
+ // an empty line while reading interactive input should return a NEWLINE
323
352
// Don't output NEWLINE if brackets are open
324
- if x .openBrackets () {
325
- continue
353
+ if x .interactive && ! x . openBrackets () {
354
+ return NEWLINE
326
355
}
327
- return NEWLINE
356
+ continue
328
357
}
329
358
case readIndent :
330
359
// Read the initial indent and get rid of it
@@ -799,20 +828,26 @@ func SetDebug(level int) {
799
828
}
800
829
801
830
// Parse a file
802
- func Parse (in io.Reader ) (ast.Mod , error ) {
803
- lex := NewLex (in )
831
+ func Parse (in io.Reader , mode string ) (ast.Mod , error ) {
832
+ lex , err := NewLex (in , mode )
833
+ if err != nil {
834
+ return nil , err
835
+ }
804
836
yyParse (lex )
805
837
return lex .mod , lex .ErrorReturn ()
806
838
}
807
839
808
840
// Parse a string
809
- func ParseString (in string ) (ast.Ast , error ) {
810
- return Parse (bytes .NewBufferString (in ))
841
+ func ParseString (in string , mode string ) (ast.Ast , error ) {
842
+ return Parse (bytes .NewBufferString (in ), mode )
811
843
}
812
844
813
845
// Lex a file only, returning a sequence of tokens
814
- func Lex (in io.Reader ) (lts LexTokens , err error ) {
815
- lex := NewLex (in )
846
+ func Lex (in io.Reader , mode string ) (lts LexTokens , err error ) {
847
+ lex , err := NewLex (in , mode )
848
+ if err != nil {
849
+ return nil , err
850
+ }
816
851
yylval := yySymType {}
817
852
for {
818
853
ret := lex .Lex (& yylval )
@@ -827,6 +862,6 @@ func Lex(in io.Reader) (lts LexTokens, err error) {
827
862
}
828
863
829
864
// Lex a string
830
- func LexString (in string ) (lts LexTokens , err error ) {
831
- return Lex (bytes .NewBufferString (in ))
865
+ func LexString (in string , mode string ) (lts LexTokens , err error ) {
866
+ return Lex (bytes .NewBufferString (in ), mode )
832
867
}
0 commit comments