import Package "package"
import Scanner "scanner"
import Parser "parser"
+import Export "export"
export Compilation
}
-func (C *Compilation) Lookup(pkg_name string) *Package.Package {
- panic "UNIMPLEMENTED";
+func (C *Compilation) Lookup(file_name string) *Package.Package {
+ for i := 0; i < C.nimports; i++ {
+ pkg := C.imports[i];
+ if pkg.file_name == file_name {
+ return pkg;
+ }
+ }
return nil;
}
func (C *Compilation) Insert(pkg *Package.Package) {
- panic "UNIMPLEMENTED";
+ if C.Lookup(pkg.file_name) != nil {
+ panic "package already inserted";
+ }
+ pkg.pno = C.nimports;
+ C.imports[C.nimports] = pkg;
+ C.nimports++;
}
func (C *Compilation) InsertImport(pkg *Package.Package) *Package.Package {
- panic "UNIMPLEMENTED";
- return nil;
+ p := C.Lookup(pkg.file_name);
+ if (p == nil) {
+ // no primary package found
+ C.Insert(pkg);
+ p = pkg;
+ }
+ return p;
+}
+
+
+func BaseName(s string) string {
+ // TODO this is not correct for non-ASCII strings!
+ i := len(s);
+ for i >= 0 && s[i] != '/' {
+ if s[i] > 128 {
+ panic "non-ASCII string"
+ }
+ i--;
+ }
+ return s[i + 1 : len(s)];
+}
+
+
+func FixExt(s string) string {
+ i := len(s) - 3; // 3 == len(".go");
+ if s[i : len(s)] == ".go" {
+ s = s[0 : i];
+ }
+ return s + ".7"
}
func (C *Compilation) Export() {
- panic "UNIMPLEMENTED";
+ file_name := FixExt(BaseName(C.src_name)); // strip src dir
+ Export.Export(file_name/*, C */);
}
import Object "object"
import Type "type"
import Package "package"
+//import Compilation "compilation"
type Exporter struct {
E.pkg_ref++;
E.WriteString(pkg.ident);
- E.WriteString(pkg.path);
+ E.WriteString(pkg.file_name);
E.WriteString(pkg.key);
}
export Export
-func Export(/*Compilation* comp, BBuffer* buf*/) {
+func Export(file_name string /*comp *Compilation.Compilation*/) {
/*
Exporter exp;
exp.Export(comp, buf);
export Package
type Package struct {
ref int;
+ file_name string;
ident string;
- path string;
key string;
scope *Globals.Scope;
+ pno int;
}
P.Trace("ChannelType");
P.Expect(Scanner.CHAN);
switch P.tok {
- case Scanner.LSS: fallthrough
- case Scanner.GTR:
+ case Scanner.SEND: fallthrough
+ case Scanner.RECV:
P.Next();
}
P.ParseType();
case Scanner.SUB: fallthrough;
case Scanner.NOT: fallthrough;
case Scanner.XOR: fallthrough;
- case Scanner.LSS: fallthrough;
- case Scanner.GTR: fallthrough;
case Scanner.MUL: fallthrough;
+ case Scanner.RECV: fallthrough;
case Scanner.AND:
P.Next();
P.ParseUnaryExpr();
return 1;
case Scanner.LAND:
return 2;
- case Scanner.EQL, Scanner.NEQ, Scanner.LSS, Scanner.LEQ, Scanner.GTR, Scanner.GEQ:
+ case Scanner.SEND, Scanner.RECV:
return 3;
- case Scanner.ADD, Scanner.SUB, Scanner.OR, Scanner.XOR:
+ case Scanner.EQL, Scanner.NEQ, Scanner.LSS, Scanner.LEQ, Scanner.GTR, Scanner.GEQ:
return 4;
- case Scanner.MUL, Scanner.QUO, Scanner.REM, Scanner.SHL, Scanner.SHR, Scanner.AND:
+ case Scanner.ADD, Scanner.SUB, Scanner.OR, Scanner.XOR:
return 5;
+ case Scanner.MUL, Scanner.QUO, Scanner.REM, Scanner.SHL, Scanner.SHR, Scanner.AND:
+ return 6;
}
return 0;
}
ADD, SUB, MUL, QUO, REM,
EQL, NEQ, LSS, LEQ, GTR, GEQ,
SHL, SHR,
+ SEND, RECV,
ADD_ASSIGN, SUB_ASSIGN, MUL_ASSIGN, QUO_ASSIGN, REM_ASSIGN,
AND_ASSIGN, OR_ASSIGN, XOR_ASSIGN, SHL_ASSIGN, SHR_ASSIGN,
LAND, LOR,
SHL;
SHR;
+
+ SEND;
+ RECV;
ADD_ASSIGN;
SUB_ASSIGN;
case SHL: return "<<";
case SHR: return ">>";
+
+ case SEND: return "-<";
+ case RECV: return "<-";
case ADD_ASSIGN: return "+=";
case SUB_ASSIGN: return "-=";
case '{': tok = LBRACE;
case '}': tok = RBRACE;
case '+': tok = S.Select3(ADD, ADD_ASSIGN, '+', INC);
- case '-': tok = S.Select3(SUB, SUB_ASSIGN, '-', DEC);
+ case '-':
+ if S.ch == '<' {
+ S.Next();
+ tok = SEND;
+ } else {
+ tok = S.Select3(SUB, SUB_ASSIGN, '-', DEC);
+ }
case '*': tok = S.Select2(MUL, MUL_ASSIGN);
case '/':
if S.ch == '/' || S.ch == '*' {
tok = S.Select2(QUO, QUO_ASSIGN);
case '%': tok = S.Select2(REM, REM_ASSIGN);
case '^': tok = S.Select2(XOR, XOR_ASSIGN);
- case '<': tok = S.Select4(LSS, LEQ, '<', SHL, SHL_ASSIGN);
+ case '<':
+ if S.ch == '-' {
+ S.Next();
+ tok = RECV;
+ } else {
+ tok = S.Select4(LSS, LEQ, '<', SHL, SHL_ASSIGN);
+ }
case '>': tok = S.Select4(GTR, GEQ, '>', SHR, SHR_ASSIGN);
case '=': tok = S.Select2(ASSIGN, EQL);
case '!': tok = S.Select2(NOT, NEQ);