Commit 1f465139 authored by Robert Griesemer's avatar Robert Griesemer

various fixes:

- missing return in import code
- proper propagation of flags to various components
- better error message when source position is missing
- cleanups

R=r
OCL=13676
CL=13676
parent 0748bf37
...@@ -17,22 +17,18 @@ import Printer "printer" ...@@ -17,22 +17,18 @@ import Printer "printer"
export Compile export Compile
func Compile(file_name string, verbose int) { func Compile(comp *Globals.Compilation, file_name string) {
src, ok := sys.readfile(file_name); src, ok := sys.readfile(file_name);
if !ok { if !ok {
print "cannot open ", file_name, "\n" print "cannot open ", file_name, "\n"
return; return;
} }
Universe.Init(); // TODO eventually this should be only needed once
comp := Globals.NewCompilation();
scanner := new(Scanner.Scanner); scanner := new(Scanner.Scanner);
scanner.Open(file_name, src); scanner.Open(file_name, src);
parser := new(Parser.Parser); parser := new(Parser.Parser);
parser.Open(comp, scanner, verbose); parser.Open(comp, scanner);
print "parsing ", file_name, "\n"; print "parsing ", file_name, "\n";
parser.ParseProgram(); parser.ParseProgram();
...@@ -40,12 +36,9 @@ func Compile(file_name string, verbose int) { ...@@ -40,12 +36,9 @@ func Compile(file_name string, verbose int) {
return; return;
} }
/*
// export // export
exp := new(Export.Exporter); if comp.flags.semantic_checks {
exp.Export(comp, Utils.FixExt(Utils.BaseName(file_name)));
// print export
Printer.PrintObject(comp, comp.pkgs[0].obj, false); Printer.PrintObject(comp, comp.pkgs[0].obj, false);
*/ Export.Export(comp, file_name);
}
} }
...@@ -121,4 +121,4 @@ func (p *T4) m5(a, b int, c float) (z T5, ok bool) { ...@@ -121,4 +121,4 @@ func (p *T4) m5(a, b int, c float) (z T5, ok bool) {
export c0, c1, v2, v3 export c0, c1, v2, v3
export T0, T1, T4, T4, T4, M0, M5, I2, f0, f1 export T0, T1, T4, T4, T4, M0, M5, I2, f0, f1
// export Node0, Node1 // this fails export Node0, Node1
...@@ -4,13 +4,13 @@ ...@@ -4,13 +4,13 @@
package Exporter package Exporter
import Utils "utils"
import Globals "globals" import Globals "globals"
import Object "object" import Object "object"
import Type "type" import Type "type"
import Universe "universe" import Universe "universe"
export Exporter // really only want to export Export()
type Exporter struct { type Exporter struct {
comp *Globals.Compilation; comp *Globals.Compilation;
debug bool; debug bool;
...@@ -65,7 +65,7 @@ func (E *Exporter) WriteString(s string) { ...@@ -65,7 +65,7 @@ func (E *Exporter) WriteString(s string) {
} }
func (E *Exporter) WriteObjTag(tag int) { func (E *Exporter) WriteObjectTag(tag int) {
if tag < 0 { if tag < 0 {
panic "tag < 0"; panic "tag < 0";
} }
...@@ -113,23 +113,12 @@ func (E *Exporter) WriteScope(scope *Globals.Scope) { ...@@ -113,23 +113,12 @@ func (E *Exporter) WriteScope(scope *Globals.Scope) {
print " {"; print " {";
} }
// determine number of objects to export
n := 0;
for p := scope.entries.first; p != nil; p = p.next {
if p.obj.exported {
n++;
}
}
E.WriteInt(n);
// export the objects, if any
if n > 0 {
for p := scope.entries.first; p != nil; p = p.next { for p := scope.entries.first; p != nil; p = p.next {
if p.obj.exported { if p.obj.exported {
E.WriteObject(p.obj); E.WriteObject(p.obj);
} }
} }
} E.WriteObjectTag(0); // terminator
if E.debug { if E.debug {
print " }"; print " }";
...@@ -144,11 +133,11 @@ func (E *Exporter) WriteObject(obj *Globals.Object) { ...@@ -144,11 +133,11 @@ func (E *Exporter) WriteObject(obj *Globals.Object) {
if obj.kind == Object.TYPE && obj.typ.obj == obj { if obj.kind == Object.TYPE && obj.typ.obj == obj {
// primary type object - handled entirely by WriteType() // primary type object - handled entirely by WriteType()
E.WriteObjTag(Object.PTYPE); E.WriteObjectTag(Object.PTYPE);
E.WriteType(obj.typ); E.WriteType(obj.typ);
} else { } else {
E.WriteObjTag(obj.kind); E.WriteObjectTag(obj.kind);
E.WriteString(obj.ident); E.WriteString(obj.ident);
E.WriteType(obj.typ); E.WriteType(obj.typ);
E.WritePackage(E.comp.pkgs[obj.pnolev]); E.WritePackage(E.comp.pkgs[obj.pnolev]);
...@@ -252,7 +241,7 @@ func (E *Exporter) WritePackage(pkg *Globals.Package) { ...@@ -252,7 +241,7 @@ func (E *Exporter) WritePackage(pkg *Globals.Package) {
func (E *Exporter) Export(comp* Globals.Compilation, file_name string) { func (E *Exporter) Export(comp* Globals.Compilation, file_name string) {
E.comp = comp; E.comp = comp;
E.debug = false; E.debug = comp.flags.debug;
E.pos = 0; E.pos = 0;
E.pkg_ref = 0; E.pkg_ref = 0;
E.type_ref = 0; E.type_ref = 0;
...@@ -275,12 +264,7 @@ func (E *Exporter) Export(comp* Globals.Compilation, file_name string) { ...@@ -275,12 +264,7 @@ func (E *Exporter) Export(comp* Globals.Compilation, file_name string) {
pkg := comp.pkgs[0]; pkg := comp.pkgs[0];
E.WritePackage(pkg); E.WritePackage(pkg);
for p := pkg.scope.entries.first; p != nil; p = p.next { E.WriteScope(pkg.scope);
if p.obj.exported {
E.WriteObject(p.obj);
}
}
E.WriteObjTag(0);
if E.debug { if E.debug {
print "\n(", E.pos, " bytes)\n"; print "\n(", E.pos, " bytes)\n";
...@@ -293,3 +277,10 @@ func (E *Exporter) Export(comp* Globals.Compilation, file_name string) { ...@@ -293,3 +277,10 @@ func (E *Exporter) Export(comp* Globals.Compilation, file_name string) {
panic "export failed"; panic "export failed";
} }
} }
export Export
func Export(comp* Globals.Compilation, pkg_name string) {
var E Exporter;
(&E).Export(comp, Utils.FixExt(Utils.BaseName(pkg_name)));
}
...@@ -75,8 +75,17 @@ type Scope struct { ...@@ -75,8 +75,17 @@ type Scope struct {
} }
export Flags;
type Flags struct {
debug bool;
semantic_checks bool;
verbose int;
}
export Compilation export Compilation
type Compilation struct { type Compilation struct {
flags *Flags;
// TODO use open arrays eventually // TODO use open arrays eventually
pkgs [256] *Package; // pkgs[0] is the current package pkgs [256] *Package; // pkgs[0] is the current package
npkgs int; npkgs int;
...@@ -134,8 +143,9 @@ func NewScope(parent *Scope) *Scope { ...@@ -134,8 +143,9 @@ func NewScope(parent *Scope) *Scope {
export NewCompilation; export NewCompilation;
func NewCompilation() *Compilation { func NewCompilation(flags *Flags) *Compilation {
comp := new(Compilation); comp := new(Compilation);
comp.flags = flags;
return comp; return comp;
} }
......
...@@ -5,19 +5,22 @@ ...@@ -5,19 +5,22 @@
package main package main
import Build "build" import Build "build"
import Globals "globals"
import Compilation "compilation" import Compilation "compilation"
// For now we are not using the flags package to minimize
// external dependencies, and because the requirements are
// very minimal at this point.
func PrintHelp() { func PrintHelp() {
print "go in go (", Build.time, ")\n"; print "go in go (", Build.time, ")\n";
print "usage:\n"; print "usage:\n";
print " go { -v | -vv | file }\n"; print " go { flag | file }\n";
/* print " -d print debug information\n";
printf("flags:\n"); print " -s enable semantic checks\n";
for (int i = 0; Flags[i].name != NULL; i++) { print " -v verbose mode\n";
printf(" %s %s\n", Flags[i].name, Flags[i].help); print " -vv very verbose mode\n";
}
*/
} }
...@@ -27,17 +30,22 @@ func main() { ...@@ -27,17 +30,22 @@ func main() {
sys.exit(1); sys.exit(1);
} }
verbose := 0; // collect flags and files
flags := new(Globals.Flags);
files := Globals.NewList();
for i := 1; i < sys.argc(); i++ { for i := 1; i < sys.argc(); i++ {
switch sys.argv(i) { switch arg := sys.argv(i); arg {
case "-v": case "-d": flags.debug = true;
verbose = 1; case "-s": flags.semantic_checks = true;
continue; case "-v": flags.verbose = 1;
case "-vv": case "-vv": flags.verbose = 2;
verbose = 2; default: files.AddStr(arg);
continue; }
} }
Compilation.Compile(sys.argv(i), verbose); // compile files
for p := files.first; p != nil; p = p.next {
comp := Globals.NewCompilation(flags);
Compilation.Compile(comp, p.str);
} }
} }
...@@ -4,13 +4,13 @@ ...@@ -4,13 +4,13 @@
package Importer package Importer
import Utils "utils"
import Globals "globals" import Globals "globals"
import Object "object" import Object "object"
import Type "type" import Type "type"
import Universe "universe" import Universe "universe"
export Importer // really only want to export Import()
type Importer struct { type Importer struct {
comp *Globals.Compilation; comp *Globals.Compilation;
debug bool; debug bool;
...@@ -74,7 +74,7 @@ func (I *Importer) ReadString() string { ...@@ -74,7 +74,7 @@ func (I *Importer) ReadString() string {
} }
func (I *Importer) ReadObjTag() int { func (I *Importer) ReadObjectTag() int {
tag := I.ReadInt(); tag := I.ReadInt();
if tag < 0 { if tag < 0 {
panic "tag < 0"; panic "tag < 0";
...@@ -125,14 +125,21 @@ func (I *Importer) ReadScope() *Globals.Scope { ...@@ -125,14 +125,21 @@ func (I *Importer) ReadScope() *Globals.Scope {
} }
scope := Globals.NewScope(nil); scope := Globals.NewScope(nil);
for n := I.ReadInt(); n > 0; n-- { for {
tag := I.ReadObjTag(); tag := I.ReadObjectTag();
scope.Insert(I.ReadObject(tag)); if tag == 0 {
break;
}
// InsertImport only needed for package scopes
// but ok to use always
scope.InsertImport(I.ReadObject(tag));
} }
if I.debug { if I.debug {
print " }"; print " }";
} }
return scope;
} }
...@@ -229,13 +236,12 @@ func (I *Importer) ReadType() *Globals.Type { ...@@ -229,13 +236,12 @@ func (I *Importer) ReadType() *Globals.Type {
case Type.FUNCTION: case Type.FUNCTION:
typ.flags = I.ReadInt(); typ.flags = I.ReadInt();
fallthrough;
case Type.STRUCT: fallthrough;
case Type.INTERFACE:
typ.scope = I.ReadScope(); typ.scope = I.ReadScope();
case Type.POINTER: fallthrough; case Type.STRUCT, Type.INTERFACE:
case Type.REFERENCE: typ.scope = I.ReadScope();
case Type.POINTER, Type.REFERENCE:
typ.elt = I.ReadType(); typ.elt = I.ReadType();
} }
...@@ -275,7 +281,7 @@ func (I *Importer) ReadPackage() *Globals.Package { ...@@ -275,7 +281,7 @@ func (I *Importer) ReadPackage() *Globals.Package {
func (I *Importer) Import(comp* Globals.Compilation, file_name string) *Globals.Package { func (I *Importer) Import(comp* Globals.Compilation, file_name string) *Globals.Package {
I.comp = comp; I.comp = comp;
I.debug = false; I.debug = comp.flags.debug;
I.buf = ""; I.buf = "";
I.pos = 0; I.pos = 0;
I.npkgs = 0; I.npkgs = 0;
...@@ -302,7 +308,7 @@ func (I *Importer) Import(comp* Globals.Compilation, file_name string) *Globals. ...@@ -302,7 +308,7 @@ func (I *Importer) Import(comp* Globals.Compilation, file_name string) *Globals.
pkg := I.ReadPackage(); pkg := I.ReadPackage();
for { for {
tag := I.ReadObjTag(); tag := I.ReadObjectTag();
if tag == 0 { if tag == 0 {
break; break;
} }
...@@ -317,3 +323,10 @@ func (I *Importer) Import(comp* Globals.Compilation, file_name string) *Globals. ...@@ -317,3 +323,10 @@ func (I *Importer) Import(comp* Globals.Compilation, file_name string) *Globals.
return pkg; return pkg;
} }
export Import
func Import(comp* Globals.Compilation, pkg_name string) *Globals.Package {
var I Importer;
return (&I).Import(comp, Utils.FixExt(pkg_name));
}
...@@ -14,13 +14,10 @@ import Import "import" ...@@ -14,13 +14,10 @@ import Import "import"
import AST "ast" import AST "ast"
// So I can submit and have a running parser for now...
const EnableSemanticTests = false;
export Parser export Parser
type Parser struct { type Parser struct {
comp *Globals.Compilation; comp *Globals.Compilation;
semantic_checks bool;
verbose, indent int; verbose, indent int;
S *Scanner.Scanner; S *Scanner.Scanner;
...@@ -74,9 +71,10 @@ func (P *Parser) Next() { ...@@ -74,9 +71,10 @@ func (P *Parser) Next() {
} }
func (P *Parser) Open(comp *Globals.Compilation, S *Scanner.Scanner, verbose int) { func (P *Parser) Open(comp *Globals.Compilation, S *Scanner.Scanner) {
P.comp = comp; P.comp = comp;
P.verbose = verbose; P.semantic_checks = comp.flags.semantic_checks;
P.verbose = comp.flags.verbose;
P.indent = 0; P.indent = 0;
P.S = S; P.S = S;
P.Next(); P.Next();
...@@ -132,7 +130,7 @@ func (P *Parser) Lookup(ident string) *Globals.Object { ...@@ -132,7 +130,7 @@ func (P *Parser) Lookup(ident string) *Globals.Object {
func (P *Parser) DeclareInScope(scope *Globals.Scope, obj *Globals.Object) { func (P *Parser) DeclareInScope(scope *Globals.Scope, obj *Globals.Object) {
if !EnableSemanticTests { if !P.semantic_checks {
return; return;
} }
obj.pnolev = P.level; obj.pnolev = P.level;
...@@ -296,7 +294,7 @@ func (P *Parser) ParseQualifiedIdent(pos int, ident string) *Globals.Object { ...@@ -296,7 +294,7 @@ func (P *Parser) ParseQualifiedIdent(pos int, ident string) *Globals.Object {
ident = P.ParseIdent(); ident = P.ParseIdent();
} }
if EnableSemanticTests { if P.semantic_checks {
obj := P.Lookup(ident); obj := P.Lookup(ident);
if obj == nil { if obj == nil {
P.Error(pos, `"` + ident + `" is not declared`); P.Error(pos, `"` + ident + `" is not declared`);
...@@ -355,7 +353,7 @@ func (P *Parser) ParseType() *Globals.Type { ...@@ -355,7 +353,7 @@ func (P *Parser) ParseType() *Globals.Type {
func (P *Parser) ParseTypeName() *Globals.Type { func (P *Parser) ParseTypeName() *Globals.Type {
P.Trace("TypeName"); P.Trace("TypeName");
if EnableSemanticTests { if P.semantic_checks {
pos := P.pos; pos := P.pos;
obj := P.ParseQualifiedIdent(-1, ""); obj := P.ParseQualifiedIdent(-1, "");
typ := obj.typ; typ := obj.typ;
...@@ -496,7 +494,7 @@ func (P *Parser) ParseAnonymousSignature() *Globals.Type { ...@@ -496,7 +494,7 @@ func (P *Parser) ParseAnonymousSignature() *Globals.Type {
if P.tok == Scanner.PERIOD { if P.tok == Scanner.PERIOD {
p0 = sig.entries.len_; p0 = sig.entries.len_;
if (EnableSemanticTests && p0 != 1) { if (P.semantic_checks && p0 != 1) {
P.Error(recv_pos, "must have exactly one receiver") P.Error(recv_pos, "must have exactly one receiver")
panic "UNIMPLEMENTED (ParseAnonymousSignature)"; panic "UNIMPLEMENTED (ParseAnonymousSignature)";
// TODO do something useful here // TODO do something useful here
...@@ -534,7 +532,7 @@ func (P *Parser) ParseNamedSignature() (name string, typ *Globals.Type) { ...@@ -534,7 +532,7 @@ func (P *Parser) ParseNamedSignature() (name string, typ *Globals.Type) {
recv_pos := P.pos; recv_pos := P.pos;
P.ParseParameters(); P.ParseParameters();
p0 = sig.entries.len_; p0 = sig.entries.len_;
if (EnableSemanticTests && p0 != 1) { if (P.semantic_checks && p0 != 1) {
print "p0 = ", p0, "\n"; print "p0 = ", p0, "\n";
P.Error(recv_pos, "must have exactly one receiver") P.Error(recv_pos, "must have exactly one receiver")
panic "UNIMPLEMENTED (ParseNamedSignature)"; panic "UNIMPLEMENTED (ParseNamedSignature)";
...@@ -653,7 +651,7 @@ func (P *Parser) ParsePointerType() *Globals.Type { ...@@ -653,7 +651,7 @@ func (P *Parser) ParsePointerType() *Globals.Type {
P.Expect(Scanner.MUL); P.Expect(Scanner.MUL);
typ := Globals.NewType(Type.POINTER); typ := Globals.NewType(Type.POINTER);
if EnableSemanticTests { if P.semantic_checks {
if P.tok == Scanner.IDENT { if P.tok == Scanner.IDENT {
if P.Lookup(P.val) == nil { if P.Lookup(P.val) == nil {
// implicit forward declaration // implicit forward declaration
...@@ -1122,7 +1120,7 @@ func (P *Parser) ParseExpression() { ...@@ -1122,7 +1120,7 @@ func (P *Parser) ParseExpression() {
func (P *Parser) ConvertToExprList(pos_list, ident_list, expr_list *Globals.List) { func (P *Parser) ConvertToExprList(pos_list, ident_list, expr_list *Globals.List) {
for p, q := pos_list.first, ident_list.first; q != nil; p, q = p.next, q.next { for p, q := pos_list.first, ident_list.first; q != nil; p, q = p.next, q.next {
pos, ident := p.val, q.str; pos, ident := p.val, q.str;
if EnableSemanticTests { if P.semantic_checks {
obj := P.Lookup(ident); obj := P.Lookup(ident);
if obj == nil { if obj == nil {
P.Error(pos, `"` + ident + `" is not declared`); P.Error(pos, `"` + ident + `" is not declared`);
...@@ -1208,24 +1206,24 @@ func (P *Parser) ParseSimpleStat() { ...@@ -1208,24 +1206,24 @@ func (P *Parser) ParseSimpleStat() {
switch P.tok { switch P.tok {
case Scanner.COLON: case Scanner.COLON:
// label declaration // label declaration
if EnableSemanticTests && ident_list.len_ != 1 { if P.semantic_checks && ident_list.len_ != 1 {
P.Error(P.pos, "illegal label declaration"); P.Error(P.pos, "illegal label declaration");
} }
P.Next(); P.Next();
case Scanner.DEFINE: case Scanner.DEFINE:
// variable declaration // variable declaration
if EnableSemanticTests && ident_list.len_ == 0 { if P.semantic_checks && ident_list.len_ == 0 {
P.Error(P.pos, "illegal left-hand side for declaration"); P.Error(P.pos, "illegal left-hand side for declaration");
} }
P.Next(); P.Next();
pos := P.pos; pos := P.pos;
val_list := P.ParseExpressionList(); val_list := P.ParseExpressionList();
if EnableSemanticTests && val_list.len_ != ident_list.len_ { if P.semantic_checks && val_list.len_ != ident_list.len_ {
P.Error(pos, "number of expressions does not match number of variables"); P.Error(pos, "number of expressions does not match number of variables");
} }
// declare variables // declare variables
if EnableSemanticTests { if P.semantic_checks {
for p, q := pos_list.first, ident_list.first; q != nil; p, q = p.next, q.next { for p, q := pos_list.first, ident_list.first; q != nil; p, q = p.next, q.next {
obj := Globals.NewObject(p.val, Object.VAR, q.str); obj := Globals.NewObject(p.val, Object.VAR, q.str);
P.Declare(obj); P.Declare(obj);
...@@ -1248,13 +1246,13 @@ func (P *Parser) ParseSimpleStat() { ...@@ -1248,13 +1246,13 @@ func (P *Parser) ParseSimpleStat() {
P.Next(); P.Next();
pos := P.pos; pos := P.pos;
val_list := P.ParseExpressionList(); val_list := P.ParseExpressionList();
if EnableSemanticTests && val_list.len_ != expr_list.len_ { if P.semantic_checks && val_list.len_ != expr_list.len_ {
P.Error(pos, "number of expressions does not match number of variables"); P.Error(pos, "number of expressions does not match number of variables");
} }
default: default:
P.ConvertToExprList(pos_list, ident_list, expr_list); P.ConvertToExprList(pos_list, ident_list, expr_list);
if EnableSemanticTests && expr_list.len_ != 1 { if P.semantic_checks && expr_list.len_ != 1 {
P.Error(P.pos, "no expression list allowed"); P.Error(P.pos, "no expression list allowed");
} }
if P.tok == Scanner.INC || P.tok == Scanner.DEC { if P.tok == Scanner.INC || P.tok == Scanner.DEC {
...@@ -1557,11 +1555,10 @@ func (P *Parser) ParseImportSpec() { ...@@ -1557,11 +1555,10 @@ func (P *Parser) ParseImportSpec() {
obj = P.ParseIdentDecl(Object.PACKAGE); obj = P.ParseIdentDecl(Object.PACKAGE);
} }
if (EnableSemanticTests && P.tok == Scanner.STRING) { if (P.semantic_checks && P.tok == Scanner.STRING) {
// TODO eventually the scanner should strip the quotes // TODO eventually the scanner should strip the quotes
pkg_name := P.val[1 : len(P.val) - 1]; // strip quotes pkg_name := P.val[1 : len(P.val) - 1]; // strip quotes
imp := new(Import.Importer); pkg := Import.Import(P.comp, pkg_name);
pkg := imp.Import(P.comp, Utils.FixExt(Utils.BaseName(pkg_name)));
if pkg != nil { if pkg != nil {
if obj == nil { if obj == nil {
// use original package name // use original package name
...@@ -1776,7 +1773,7 @@ func (P *Parser) ParseDeclaration() { ...@@ -1776,7 +1773,7 @@ func (P *Parser) ParseDeclaration() {
// Program // Program
func (P *Parser) ResolveUndefTypes() { func (P *Parser) ResolveUndefTypes() {
if !EnableSemanticTests { if !P.semantic_checks {
return; return;
} }
...@@ -1798,7 +1795,7 @@ func (P *Parser) ResolveUndefTypes() { ...@@ -1798,7 +1795,7 @@ func (P *Parser) ResolveUndefTypes() {
func (P *Parser) MarkExports() { func (P *Parser) MarkExports() {
if !EnableSemanticTests { if !P.semantic_checks {
return; return;
} }
...@@ -1820,7 +1817,7 @@ func (P *Parser) MarkExports() { ...@@ -1820,7 +1817,7 @@ func (P *Parser) MarkExports() {
} }
} else { } else {
// TODO need to report proper src position // TODO need to report proper src position
P.Error(0, `"` + p.str + `" is not declared - cannot be exported`); P.Error(-1, `"` + p.str + `" is not declared - cannot be exported`);
} }
} }
} }
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
package Scanner package Scanner
import Utils "utils"
export export
ILLEGAL, EOF, IDENT, STRING, NUMBER, ILLEGAL, EOF, IDENT, STRING, NUMBER,
COMMA, COLON, SEMICOLON, PERIOD, COMMA, COLON, SEMICOLON, PERIOD,
...@@ -231,6 +234,18 @@ func TokenName(tok int) string { ...@@ -231,6 +234,18 @@ func TokenName(tok int) string {
} }
func init() {
Keywords = new(map [string] int);
for i := KEYWORDS_BEG; i <= KEYWORDS_END; i++ {
Keywords[TokenName(i)] = i;
}
// Provide column information in error messages for gri only...
VerboseMsgs = Utils.GetEnv("USER") == "gri";
}
func is_whitespace(ch int) bool { func is_whitespace(ch int) bool {
return ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t'; return ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t';
} }
...@@ -370,28 +385,6 @@ bad: ...@@ -370,28 +385,6 @@ bad:
} }
func IsUser(username string) bool {
for i := 0; i < sys.envc(); i++ {
if sys.envv(i) == "USER=" + username {
return true;
}
}
return false;
}
func Init() {
Keywords = new(map [string] int);
for i := KEYWORDS_BEG; i <= KEYWORDS_END; i++ {
Keywords[TokenName(i)] = i;
}
// Provide column information in error messages for gri only...
VerboseMsgs = IsUser("gri");
}
// Compute (line, column) information for a given source position. // Compute (line, column) information for a given source position.
func (S *Scanner) LineCol(pos int) (line, col int) { func (S *Scanner) LineCol(pos int) (line, col int) {
line = 1; line = 1;
...@@ -416,13 +409,21 @@ func (S *Scanner) LineCol(pos int) (line, col int) { ...@@ -416,13 +409,21 @@ func (S *Scanner) LineCol(pos int) (line, col int) {
func (S *Scanner) Error(pos int, msg string) { func (S *Scanner) Error(pos int, msg string) {
const errdist = 10; const errdist = 10;
delta := pos - S.errpos; // may be negative! delta := pos - S.errpos; // may be negative!
if delta < errdist || delta > errdist || S.nerrors == 0 { if delta < 0 {
delta = -delta;
}
if delta > errdist || S.nerrors == 0 /* always report first error */ {
print S.filename;
if pos >= 0 {
// print position
line, col := S.LineCol(pos); line, col := S.LineCol(pos);
if VerboseMsgs { if VerboseMsgs {
print S.filename, ":", line, ":", col, ": ", msg, "\n"; print ":", line, ":", col;
} else { } else {
print S.filename, ":", line, ": ", msg, "\n"; print ":", line;
} }
}
print ": ", msg, "\n";
S.nerrors++; S.nerrors++;
S.errpos = pos; S.errpos = pos;
} }
...@@ -434,10 +435,6 @@ func (S *Scanner) Error(pos int, msg string) { ...@@ -434,10 +435,6 @@ func (S *Scanner) Error(pos int, msg string) {
func (S *Scanner) Open(filename, src string) { func (S *Scanner) Open(filename, src string) {
if Keywords == nil {
Init();
}
S.filename = filename; S.filename = filename;
S.nerrors = 0; S.nerrors = 0;
S.errpos = 0; S.errpos = 0;
......
...@@ -101,8 +101,7 @@ func Register(typ *Globals.Type) *Globals.Type { ...@@ -101,8 +101,7 @@ func Register(typ *Globals.Type) *Globals.Type {
} }
export Init func init() {
func Init() {
scope = Globals.NewScope(nil); // universe has no parent scope = Globals.NewScope(nil); // universe has no parent
types = Globals.NewList(); types = Globals.NewList();
......
...@@ -27,3 +27,16 @@ func FixExt(s string) string { ...@@ -27,3 +27,16 @@ func FixExt(s string) string {
} }
return s + ".7"; return s + ".7";
} }
export GetEnv
func GetEnv(key string) string {
n := len(key);
for i := 0; i < sys.envc(); i++ {
v := sys.envv(i);
if v[0 : n] == key {
return v[n + 1 : len(v)]; // +1: skip "="
}
}
return "";
}
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