Commit 6349d38e authored by Robert Griesemer's avatar Robert Griesemer

- fixed semicolon handling in pretty printer

- some scanner cleanup
- new pretty-printed code can be compiled again (for some files)

R=r
OCL=16272
CL=16272
parent 77a911bc
...@@ -14,9 +14,9 @@ export type Parser struct { ...@@ -14,9 +14,9 @@ export type Parser struct {
scanner *Scanner.Scanner; scanner *Scanner.Scanner;
tokchan *<-chan *Scanner.Token; tokchan *<-chan *Scanner.Token;
// Token // Scanner.Token
tok int; // one token look-ahead
pos int; // token source position pos int; // token source position
tok int; // one token look-ahead
val string; // token value (for IDENT, NUMBER, STRING only) val string; // token value (for IDENT, NUMBER, STRING only)
// Nesting level // Nesting level
...@@ -54,7 +54,7 @@ func (P *Parser) Ecart() { ...@@ -54,7 +54,7 @@ func (P *Parser) Ecart() {
func (P *Parser) Next() { func (P *Parser) Next() {
if P.tokchan == nil { if P.tokchan == nil {
P.tok, P.pos, P.val = P.scanner.Scan(); P.pos, P.tok, P.val = P.scanner.Scan();
} else { } else {
t := <-P.tokchan; t := <-P.tokchan;
P.tok, P.pos, P.val = t.tok, t.pos, t.val; P.tok, P.pos, P.val = t.tok, t.pos, t.val;
...@@ -336,22 +336,22 @@ func (P *Parser) ParseResultList() { ...@@ -336,22 +336,22 @@ func (P *Parser) ParseResultList() {
func (P *Parser) ParseResult() *AST.List { func (P *Parser) ParseResult() *AST.List {
P.Trace("Result"); P.Trace("Result");
var result *AST.List;
if P.tok == Scanner.LPAREN { if P.tok == Scanner.LPAREN {
P.Next(); result = P.ParseParameters();
P.ParseResultList();
for P.tok == Scanner.COMMA {
P.Next();
P.ParseResultList();
}
P.Expect(Scanner.RPAREN);
} else { } else {
// anonymous result typ, ok := P.TryType();
P.TryType(); if ok {
vars := new(AST.VarDeclList);
vars.typ = typ;
list := AST.NewList();
list.Add(vars);
result = list;
}
} }
P.Ecart(); P.Ecart();
return nil return result;
} }
...@@ -1008,11 +1008,7 @@ func (P *Parser) ParseControlClause(keyword int) *AST.ControlClause { ...@@ -1008,11 +1008,7 @@ func (P *Parser) ParseControlClause(keyword int) *AST.ControlClause {
} }
} }
} else { } else {
//ctrl.expr, ctrl.has_expr = ctrl.init, ctrl.has_init; ctrl.expr, ctrl.has_expr = ctrl.init, ctrl.has_init;
ctrl.expr = ctrl.init;
ctrl.has_expr = ctrl.has_init;
ctrl.init, ctrl.has_init = AST.NIL, false; ctrl.init, ctrl.has_init = AST.NIL, false;
} }
} }
......
...@@ -10,25 +10,50 @@ import AST "ast" ...@@ -10,25 +10,50 @@ import AST "ast"
// Printer implements AST.Visitor // Printer implements AST.Visitor
type Printer struct { type Printer struct {
indent int; level int; // true scope level
indent int; // indentation level
semi bool; // pending ";"
newl bool; // pending "\n"
prec int; // operator precedence prec int; // operator precedence
} }
func (P *Printer) NewLine(delta int) { func (P *Printer) String(s string) {
P.indent += delta; if P.semi && P.level > 0 { // no semicolons at level 0
if P.indent < 0 { print(";");
panic("negative indent");
} }
print("\n"); if P.newl {
for i := P.indent; i > 0; i-- { print("\n");
print("\t"); for i := P.indent; i > 0; i-- {
print("\t");
}
} }
print(s);
P.newl, P.semi = false, false;
} }
func (P *Printer) String(s string) { func (P *Printer) NewLine() { // explicit "\n"
print(s); print("\n");
P.semi, P.newl = false, true;
}
func (P *Printer) OpenScope(paren string) {
P.semi, P.newl = false, false;
P.String(paren);
P.level++;
P.indent++;
P.newl = true;
}
func (P *Printer) CloseScope(paren string) {
P.level--;
P.indent--;
P.newl = true;
P.String(paren);
P.semi, P.newl = false, true;
} }
...@@ -70,6 +95,11 @@ func (P *Printer) DoFunctionType(x *AST.FunctionType) { ...@@ -70,6 +95,11 @@ func (P *Printer) DoFunctionType(x *AST.FunctionType) {
P.String("("); P.String("(");
P.PrintList(x.params); P.PrintList(x.params);
P.String(")"); P.String(")");
if x.result != nil {
P.String(" (");
P.PrintList(x.result);
P.String(")");
}
} }
...@@ -82,19 +112,13 @@ func (P *Printer) DoArrayType(x *AST.ArrayType) { ...@@ -82,19 +112,13 @@ func (P *Printer) DoArrayType(x *AST.ArrayType) {
func (P *Printer) DoStructType(x *AST.StructType) { func (P *Printer) DoStructType(x *AST.StructType) {
P.String("struct {"); P.String("struct ");
if x.fields.len() > 0 { P.OpenScope("{");
P.NewLine(1); for i := 0; i < x.fields.len(); i++ {
for i := 0; i < x.fields.len(); i++ { P.Print(x.fields.at(i));
if i > 0 { P.newl, P.semi = true, true;
P.NewLine(0);
}
P.Print(x.fields.at(i));
P.String(";");
}
P.NewLine(-1);
} }
P.String("}"); P.CloseScope("}");
} }
...@@ -117,19 +141,13 @@ func (P *Printer) DoChannelType(x *AST.ChannelType) { ...@@ -117,19 +141,13 @@ func (P *Printer) DoChannelType(x *AST.ChannelType) {
func (P *Printer) DoInterfaceType(x *AST.InterfaceType) { func (P *Printer) DoInterfaceType(x *AST.InterfaceType) {
P.String("interface {"); P.String("interface ");
if x.methods.len() > 0 { P.OpenScope("{");
P.NewLine(1); for i := 0; i < x.methods.len(); i++ {
for i := 0; i < x.methods.len(); i++ { P.Print(x.methods.at(i));
if i > 0 { P.newl, P.semi = true, true;
P.NewLine(0);
}
P.Print(x.methods.at(i));
P.String(";");
}
P.NewLine(-1);
} }
P.String("}"); P.CloseScope("}");
} }
...@@ -160,6 +178,7 @@ func (P *Printer) DoConstDecl(x *AST.ConstDecl) { ...@@ -160,6 +178,7 @@ func (P *Printer) DoConstDecl(x *AST.ConstDecl) {
P.Print(x.typ); P.Print(x.typ);
P.String(" = "); P.String(" = ");
P.Print(x.val); P.Print(x.val);
P.semi = true;
} }
...@@ -167,6 +186,7 @@ func (P *Printer) DoTypeDecl(x *AST.TypeDecl) { ...@@ -167,6 +186,7 @@ func (P *Printer) DoTypeDecl(x *AST.TypeDecl) {
P.Print(x.ident); P.Print(x.ident);
P.String(" "); P.String(" ");
P.Print(x.typ); P.Print(x.typ);
P.semi = true;
} }
...@@ -178,6 +198,7 @@ func (P *Printer) DoVarDecl(x *AST.VarDecl) { ...@@ -178,6 +198,7 @@ func (P *Printer) DoVarDecl(x *AST.VarDecl) {
P.String(" = "); P.String(" = ");
P.PrintList(x.vals); P.PrintList(x.vals);
} }
P.semi = true;
} }
...@@ -199,15 +220,13 @@ func (P *Printer) DoFuncDecl(x *AST.FuncDecl) { ...@@ -199,15 +220,13 @@ func (P *Printer) DoFuncDecl(x *AST.FuncDecl) {
} }
P.DoIdent(x.ident); P.DoIdent(x.ident);
P.DoFunctionType(x.typ); P.DoFunctionType(x.typ);
P.String(" ");
if x.body != nil { if x.body != nil {
P.DoBlock(x.body); P.DoBlock(x.body);
} else { } else {
P.String(";"); P.String(" ;");
} }
P.NewLine(0); P.NewLine();
P.NewLine(0); P.NewLine();
P.NewLine(0);
} }
...@@ -226,19 +245,17 @@ func (P *Printer) DoDeclaration(x *AST.Declaration) { ...@@ -226,19 +245,17 @@ func (P *Printer) DoDeclaration(x *AST.Declaration) {
case 1: case 1:
P.Print(x.decls.at(0)); P.Print(x.decls.at(0));
default: default:
P.String("("); P.OpenScope(" (");
P.NewLine(1);
for i := 0; i < x.decls.len(); i++ { for i := 0; i < x.decls.len(); i++ {
if i > 0 {
P.NewLine(0);
}
P.Print(x.decls.at(i)); P.Print(x.decls.at(i));
P.String(";"); P.newl, P.semi = true, true;
} }
P.NewLine(-1); P.CloseScope(")");
P.String(")"); }
if P.level == 0 {
P.NewLine();
} }
P.NewLine(0); P.newl = true;
} }
...@@ -326,23 +343,18 @@ func (P *Printer) DoFunctionLit(x *AST.FunctionLit) { ...@@ -326,23 +343,18 @@ func (P *Printer) DoFunctionLit(x *AST.FunctionLit) {
// Statements // Statements
func (P *Printer) DoBlock(x *AST.Block) { func (P *Printer) DoBlock(x *AST.Block) {
P.String("{"); P.OpenScope("{");
if x.stats != nil { for i := 0; i < x.stats.len(); i++ {
P.NewLine(1); P.Print(x.stats.at(i));
for i := 0; i < x.stats.len(); i++ { P.newl = true;
if i > 0 {
P.NewLine(0);
}
P.Print(x.stats.at(i));
}
P.NewLine(-1);
} }
P.String("}"); P.CloseScope("}");
} }
func (P *Printer) DoLabel(x *AST.Label) { func (P *Printer) DoLabel(x *AST.Label) {
P.NewLine(-1); P.indent--;
P.newl = true;
P.Print(x.ident); P.Print(x.ident);
P.String(":"); P.String(":");
P.indent++; P.indent++;
...@@ -351,7 +363,7 @@ func (P *Printer) DoLabel(x *AST.Label) { ...@@ -351,7 +363,7 @@ func (P *Printer) DoLabel(x *AST.Label) {
func (P *Printer) DoExprStat(x *AST.ExprStat) { func (P *Printer) DoExprStat(x *AST.ExprStat) {
P.Print(x.expr); P.Print(x.expr);
//P.String(";"); P.semi = true;
} }
...@@ -359,7 +371,7 @@ func (P *Printer) DoAssignment(x *AST.Assignment) { ...@@ -359,7 +371,7 @@ func (P *Printer) DoAssignment(x *AST.Assignment) {
P.PrintList(x.lhs); P.PrintList(x.lhs);
P.String(" " + Scanner.TokenName(x.tok) + " "); P.String(" " + Scanner.TokenName(x.tok) + " ");
P.PrintList(x.rhs); P.PrintList(x.rhs);
//P.String(";"); P.semi = true;
} }
...@@ -367,15 +379,19 @@ func (P *Printer) PrintControlClause(x *AST.ControlClause) { ...@@ -367,15 +379,19 @@ func (P *Printer) PrintControlClause(x *AST.ControlClause) {
if x.has_init { if x.has_init {
P.String(" "); P.String(" ");
P.Print(x.init); P.Print(x.init);
P.String(";"); P.semi = true;
P.String("");
} }
if x.has_expr { if x.has_expr {
P.String(" "); P.String(" ");
P.Print(x.expr); P.Print(x.expr);
P.semi = false;
} }
if x.has_post { if x.has_post {
P.String("; "); P.semi = true;
P.String(" ");
P.Print(x.post); P.Print(x.post);
P.semi = false;
} }
P.String(" "); P.String(" ");
} }
...@@ -386,6 +402,7 @@ func (P *Printer) DoIfStat(x *AST.IfStat) { ...@@ -386,6 +402,7 @@ func (P *Printer) DoIfStat(x *AST.IfStat) {
P.PrintControlClause(x.ctrl); P.PrintControlClause(x.ctrl);
P.DoBlock(x.then); P.DoBlock(x.then);
if x.has_else { if x.has_else {
P.newl = false;
P.String(" else "); P.String(" else ");
P.Print(x.else_); P.Print(x.else_);
} }
...@@ -399,19 +416,6 @@ func (P *Printer) DoForStat(x *AST.ForStat) { ...@@ -399,19 +416,6 @@ func (P *Printer) DoForStat(x *AST.ForStat) {
} }
/*
func AnalyzeCase(x *AST.SwitchStat) bool {
for i := 0; i < x.cases.len(); i++ {
clause := x.cases.at(i).(AST.CaseClause);
if clause.stats.len() > 1 {
return false;
}
}
return true;
}
*/
func (P *Printer) DoCaseClause(x *AST.CaseClause) { func (P *Printer) DoCaseClause(x *AST.CaseClause) {
if x.exprs != nil { if x.exprs != nil {
P.String("case "); P.String("case ");
...@@ -421,57 +425,42 @@ func (P *Printer) DoCaseClause(x *AST.CaseClause) { ...@@ -421,57 +425,42 @@ func (P *Printer) DoCaseClause(x *AST.CaseClause) {
P.String("default:"); P.String("default:");
} }
n := x.stats.len(); P.OpenScope("");
m := n; for i := 0; i < x.stats.len(); i++ {
if x.falls { P.Print(x.stats.at(i));
m++; P.newl = true;
} }
if x.falls {
if m == 0 { P.String("fallthrough");
P.NewLine(0);
} else {
P.NewLine(1);
for i := 0; i < n; i++ {
if i > 0 {
P.NewLine(0);
}
P.Print(x.stats.at(i));
}
if x.falls {
if n > 0 {
P.NewLine(0);
}
P.String("fallthrough;");
}
P.NewLine(-1);
} }
P.CloseScope("");
} }
func (P *Printer) DoSwitchStat(x *AST.SwitchStat) { func (P *Printer) DoSwitchStat(x *AST.SwitchStat) {
P.String("switch"); P.String("switch ");
P.PrintControlClause(x.ctrl); P.PrintControlClause(x.ctrl);
P.String("{"); P.OpenScope("{");
P.NewLine(0); P.indent--;
for i := 0; i < x.cases.len(); i++ { for i := 0; i < x.cases.len(); i++ {
P.Print(x.cases.at(i)); P.Print(x.cases.at(i));
} }
P.NewLine(0); P.indent++;
P.String("}"); P.CloseScope("}");
} }
func (P *Printer) DoReturnStat(x *AST.ReturnStat) { func (P *Printer) DoReturnStat(x *AST.ReturnStat) {
P.String("return "); P.String("return ");
P.PrintList(x.res); P.PrintList(x.res);
P.String(";"); P.semi = true;
} }
func (P *Printer) DoIncDecStat(x *AST.IncDecStat) { func (P *Printer) DoIncDecStat(x *AST.IncDecStat) {
P.Print(x.expr); P.Print(x.expr);
P.String(Scanner.TokenName(x.tok)); P.String(Scanner.TokenName(x.tok));
//P.String(";"); P.semi = true;
} }
...@@ -481,14 +470,14 @@ func (P *Printer) DoControlFlowStat(x *AST.ControlFlowStat) { ...@@ -481,14 +470,14 @@ func (P *Printer) DoControlFlowStat(x *AST.ControlFlowStat) {
P.String(" "); P.String(" ");
P.Print(x.label); P.Print(x.label);
} }
P.String(";"); P.semi = true;
} }
func (P *Printer) DoGoStat(x *AST.GoStat) { func (P *Printer) DoGoStat(x *AST.GoStat) {
P.String("go "); P.String("go ");
P.Print(x.expr); P.Print(x.expr);
P.String(";"); P.semi = true;
} }
...@@ -498,10 +487,12 @@ func (P *Printer) DoGoStat(x *AST.GoStat) { ...@@ -498,10 +487,12 @@ func (P *Printer) DoGoStat(x *AST.GoStat) {
func (P *Printer) DoProgram(x *AST.Program) { func (P *Printer) DoProgram(x *AST.Program) {
P.String("package "); P.String("package ");
P.DoIdent(x.ident); P.DoIdent(x.ident);
P.NewLine(0); P.NewLine();
for i := 0; i < x.decls.len(); i++ { for i := 0; i < x.decls.len(); i++ {
P.Print(x.decls.at(i)); P.Print(x.decls.at(i));
} }
P.newl = true;
P.String("");
} }
......
...@@ -10,54 +10,25 @@ import Utils "utils" ...@@ -10,54 +10,25 @@ import Utils "utils"
export const ( export const (
ILLEGAL = iota; ILLEGAL = iota;
EOF;
IDENT; IDENT;
INT; INT;
FLOAT; FLOAT;
STRING; STRING;
EOF;
COMMA;
COLON;
SEMICOLON;
PERIOD;
LPAREN;
RPAREN;
LBRACK;
RBRACK;
LBRACE;
RBRACE;
ASSIGN;
DEFINE;
INC;
DEC;
NOT;
AND;
OR;
XOR;
ADD; ADD;
SUB; SUB;
MUL; MUL;
QUO; QUO;
REM; REM;
EQL; AND;
NEQ; OR;
LSS; XOR;
LEQ;
GTR;
GEQ;
SHL; SHL;
SHR; SHR;
ARROW;
HASH;
ADD_ASSIGN; ADD_ASSIGN;
SUB_ASSIGN; SUB_ASSIGN;
MUL_ASSIGN; MUL_ASSIGN;
...@@ -67,13 +38,40 @@ export const ( ...@@ -67,13 +38,40 @@ export const (
AND_ASSIGN; AND_ASSIGN;
OR_ASSIGN; OR_ASSIGN;
XOR_ASSIGN; XOR_ASSIGN;
SHL_ASSIGN; SHL_ASSIGN;
SHR_ASSIGN; SHR_ASSIGN;
LAND; LAND;
LOR; LOR;
ARROW;
INC;
DEC;
EQL;
NEQ;
LSS;
LEQ;
GTR;
GEQ;
ASSIGN;
DEFINE;
NOT;
ELLIPSIS;
HASH;
LPAREN;
RPAREN;
LBRACK;
RBRACK;
LBRACE;
RBRACE;
COMMA;
SEMICOLON;
COLON;
PERIOD;
// keywords // keywords
KEYWORDS_BEG; KEYWORDS_BEG;
BREAK; BREAK;
...@@ -81,21 +79,25 @@ export const ( ...@@ -81,21 +79,25 @@ export const (
CHAN; CHAN;
CONST; CONST;
CONTINUE; CONTINUE;
DEFAULT; DEFAULT;
ELSE; ELSE;
EXPORT; EXPORT;
FALLTHROUGH; FALLTHROUGH;
FOR; FOR;
FUNC; FUNC;
GO; GO;
GOTO; GOTO;
IF; IF;
IMPORT; IMPORT;
INTERFACE; INTERFACE;
MAP; MAP;
PACKAGE; PACKAGE;
RANGE; RANGE;
RETURN; RETURN;
SELECT; SELECT;
STRUCT; STRUCT;
SWITCH; SWITCH;
...@@ -105,61 +107,28 @@ export const ( ...@@ -105,61 +107,28 @@ export const (
) )
var Keywords *map [string] int;
var VerboseMsgs bool; // error message customization
export func TokenName(tok int) string { export func TokenName(tok int) string {
switch (tok) { switch (tok) {
case ILLEGAL: return "illegal"; case ILLEGAL: return "ILLEGAL";
case EOF: return "eof";
case IDENT: return "ident";
case INT: return "int";
case FLOAT: return "float";
case STRING: return "string";
case COMMA: return ",";
case COLON: return ":";
case SEMICOLON: return ";";
case PERIOD: return ".";
case LPAREN: return "(";
case RPAREN: return ")";
case LBRACK: return "[";
case RBRACK: return "]";
case LBRACE: return "LBRACE";
case RBRACE: return "RBRACE";
case ASSIGN: return "=";
case DEFINE: return ":=";
case INC: return "++"; case IDENT: return "IDENT";
case DEC: return "--"; case INT: return "INT";
case NOT: return "!"; case FLOAT: return "FLOAT";
case STRING: return "STRING";
case EOF: return "EOF";
case AND: return "&";
case OR: return "|";
case XOR: return "^";
case ADD: return "+"; case ADD: return "+";
case SUB: return "-"; case SUB: return "-";
case MUL: return "*"; case MUL: return "*";
case QUO: return "/"; case QUO: return "/";
case REM: return "%"; case REM: return "%";
case EQL: return "=="; case AND: return "&";
case NEQ: return "!="; case OR: return "|";
case LSS: return "<"; case XOR: return "^";
case LEQ: return "<=";
case GTR: return ">";
case GEQ: return ">=";
case SHL: return "<<"; case SHL: return "<<";
case SHR: return ">>"; case SHR: return ">>";
case ARROW: return "<-";
case HASH: return "#";
case ADD_ASSIGN: return "+="; case ADD_ASSIGN: return "+=";
case SUB_ASSIGN: return "-="; case SUB_ASSIGN: return "-=";
case MUL_ASSIGN: return "+="; case MUL_ASSIGN: return "+=";
...@@ -169,33 +138,64 @@ export func TokenName(tok int) string { ...@@ -169,33 +138,64 @@ export func TokenName(tok int) string {
case AND_ASSIGN: return "&="; case AND_ASSIGN: return "&=";
case OR_ASSIGN: return "|="; case OR_ASSIGN: return "|=";
case XOR_ASSIGN: return "^="; case XOR_ASSIGN: return "^=";
case SHL_ASSIGN: return "<<="; case SHL_ASSIGN: return "<<=";
case SHR_ASSIGN: return ">>="; case SHR_ASSIGN: return ">>=";
case LAND: return "&&"; case LAND: return "&&";
case LOR: return "||"; case LOR: return "||";
case ARROW: return "<-";
case INC: return "++";
case DEC: return "--";
case EQL: return "==";
case NEQ: return "!=";
case LSS: return "<";
case LEQ: return "<=";
case GTR: return ">";
case GEQ: return ">=";
case ASSIGN: return "=";
case DEFINE: return ":=";
case NOT: return "!";
case ELLIPSIS: return "...";
case HASH: return "#";
case LPAREN: return "(";
case RPAREN: return ")";
case LBRACK: return "[";
case RBRACK: return "]";
case LBRACE: return "LBRACE";
case RBRACE: return "RBRACE";
case COMMA: return ",";
case SEMICOLON: return ";";
case COLON: return ":";
case PERIOD: return ".";
case BREAK: return "break"; case BREAK: return "break";
case CASE: return "case"; case CASE: return "case";
case CHAN: return "chan"; case CHAN: return "chan";
case CONST: return "const"; case CONST: return "const";
case CONTINUE: return "continue"; case CONTINUE: return "continue";
case DEFAULT: return "default"; case DEFAULT: return "default";
case ELSE: return "else"; case ELSE: return "else";
case EXPORT: return "export"; case EXPORT: return "export";
case FALLTHROUGH: return "fallthrough"; case FALLTHROUGH: return "fallthrough";
case FOR: return "for"; case FOR: return "for";
case FUNC: return "func"; case FUNC: return "func";
case GO: return "go"; case GO: return "go";
case GOTO: return "goto"; case GOTO: return "goto";
case IF: return "if"; case IF: return "if";
case IMPORT: return "import"; case IMPORT: return "import";
case INTERFACE: return "interface"; case INTERFACE: return "interface";
case MAP: return "map"; case MAP: return "map";
case PACKAGE: return "package"; case PACKAGE: return "package";
case RANGE: return "range"; case RANGE: return "range";
case RETURN: return "return"; case RETURN: return "return";
case SELECT: return "select"; case SELECT: return "select";
case STRUCT: return "struct"; case STRUCT: return "struct";
case SWITCH: return "switch"; case SWITCH: return "switch";
...@@ -203,7 +203,7 @@ export func TokenName(tok int) string { ...@@ -203,7 +203,7 @@ export func TokenName(tok int) string {
case VAR: return "var"; case VAR: return "var";
} }
return "???"; panic("UNREACHABLE");
} }
...@@ -227,10 +227,14 @@ export func Precedence(tok int) int { ...@@ -227,10 +227,14 @@ export func Precedence(tok int) int {
} }
var Keywords *map [string] int;
var VerboseMsgs bool; // error message customization
func init() { func init() {
Keywords = new(map [string] int); Keywords = new(map [string] int);
for i := KEYWORDS_BEG; i <= KEYWORDS_END; i++ { for i := KEYWORDS_BEG + 1; i < KEYWORDS_END; i++ {
Keywords[TokenName(i)] = i; Keywords[TokenName(i)] = i;
} }
...@@ -277,7 +281,6 @@ export type Scanner struct { ...@@ -277,7 +281,6 @@ export type Scanner struct {
// Read the next Unicode char into S.ch. // Read the next Unicode char into S.ch.
// S.ch < 0 means end-of-file. // S.ch < 0 means end-of-file.
//
func (S *Scanner) Next() { func (S *Scanner) Next() {
const ( const (
Bit1 = 7; Bit1 = 7;
...@@ -718,12 +721,12 @@ func (S *Scanner) Select4(tok0, tok1, ch2, tok2, tok3 int) int { ...@@ -718,12 +721,12 @@ func (S *Scanner) Select4(tok0, tok1, ch2, tok2, tok3 int) int {
} }
func (S *Scanner) Scan() (tok, pos int, val string) { func (S *Scanner) Scan() (pos, tok int, val string) {
S.SkipWhitespace(); S.SkipWhitespace();
ch := S.ch; ch := S.ch;
tok = ILLEGAL;
pos = S.chpos; pos = S.chpos;
tok = ILLEGAL;
switch { switch {
case is_letter(ch): tok, val = S.ScanIdentifier(); case is_letter(ch): tok, val = S.ScanIdentifier();
...@@ -739,6 +742,12 @@ func (S *Scanner) Scan() (tok, pos int, val string) { ...@@ -739,6 +742,12 @@ func (S *Scanner) Scan() (tok, pos int, val string) {
case '.': case '.':
if digit_val(S.ch) < 10 { if digit_val(S.ch) < 10 {
tok, val = S.ScanNumber(true); tok, val = S.ScanNumber(true);
} else if S.ch == '.' {
S.Next();
if S.ch == '.' {
S.Next();
tok = ELLIPSIS;
}
} else { } else {
tok = PERIOD; tok = PERIOD;
} }
...@@ -782,7 +791,7 @@ func (S *Scanner) Scan() (tok, pos int, val string) { ...@@ -782,7 +791,7 @@ func (S *Scanner) Scan() (tok, pos int, val string) {
} }
} }
return tok, pos, val; return pos, tok, val;
} }
...@@ -798,7 +807,7 @@ func (S *Scanner) TokenStream() *<-chan *Token { ...@@ -798,7 +807,7 @@ func (S *Scanner) TokenStream() *<-chan *Token {
go func(S *Scanner, ch *chan <- *Token) { go func(S *Scanner, ch *chan <- *Token) {
for { for {
t := new(Token); t := new(Token);
t.tok, t.pos, t.val = S.Scan(); t.pos, t.tok, t.val = S.Scan();
ch <- t; ch <- t;
if t.tok == EOF { if t.tok == EOF {
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment