Commit c7fb27f6 authored by Robert Griesemer's avatar Robert Griesemer

- more steps towards automatic recursive compilation of dependencies

- make forward declarations of types match 6g
- better factoring

R=r
OCL=14059
CL=14059
parent 5649c23c
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package Compilation package Compilation
import Platform "platform"
import Utils "utils" import Utils "utils"
import Globals "globals" import Globals "globals"
import Object "object" import Object "object"
...@@ -12,16 +13,77 @@ import Universe "universe" ...@@ -12,16 +13,77 @@ import Universe "universe"
import Scanner "scanner" import Scanner "scanner"
import AST "ast" import AST "ast"
import Parser "parser" import Parser "parser"
import Export "export" import Importer "import"
import Exporter "export"
import Printer "printer" import Printer "printer"
import Verifier "verifier" import Verifier "verifier"
export func Compile(flags *Globals.Flags, filename string) { func ReadImport(comp* Globals.Compilation, filename string, update bool) (data string, ok bool) {
if filename == "" {
panic "illegal package file name";
}
// see if it just works
data, ok = Platform.ReadObjectFile(filename);
if ok {
return data, ok;
}
if filename[0] == '/' {
// absolute path
panic `don't know how to handle absolute import file path "` + filename + `"`;
}
// relative path
// try relative to the $GOROOT/pkg directory
std_filename := Platform.GOROOT + "/pkg/" + filename;
data, ok = Platform.ReadObjectFile(std_filename);
if ok {
return data, ok;
}
if !update {
return "", false;
}
// TODO BIG HACK - fix this!
// look for a src file
// see if it just works
data, ok = Platform.ReadSourceFile(filename);
if ok {
comp.env.Compile(comp.flags, comp.env, filename + Platform.src_file_ext);
data, ok = ReadImport(comp, filename, false);
if ok {
return data, ok;
}
}
return "", false;
}
export func Import(comp *Globals.Compilation, pkg_file string) *Globals.Package {
data, ok := ReadImport(comp, pkg_file, comp.flags.update_packages)
var pkg *Globals.Package;
if ok {
pkg = Importer.Import(comp, data);
}
return pkg;
}
export func Export(comp *Globals.Compilation) string {
panic "UNIMPLEMENTED";
return "";
}
export func Compile(flags *Globals.Flags, env* Globals.Environment, filename string) {
// setup compilation // setup compilation
comp := new(Globals.Compilation); comp := new(Globals.Compilation);
comp.flags = flags; comp.flags = flags;
comp.Compile = &Compile; comp.env = env;
src, ok := sys.readfile(filename); src, ok := sys.readfile(filename);
if !ok { if !ok {
...@@ -29,8 +91,10 @@ export func Compile(flags *Globals.Flags, filename string) { ...@@ -29,8 +91,10 @@ export func Compile(flags *Globals.Flags, filename string) {
return; return;
} }
print filename, "\n"; if flags.verbosity > 0 {
print filename, "\n";
}
scanner := new(Scanner.Scanner); scanner := new(Scanner.Scanner);
scanner.Open(filename, src); scanner.Open(filename, src);
...@@ -58,5 +122,5 @@ export func Compile(flags *Globals.Flags, filename string) { ...@@ -58,5 +122,5 @@ export func Compile(flags *Globals.Flags, filename string) {
Printer.PrintObject(comp, comp.pkg_list[0].obj, false); Printer.PrintObject(comp, comp.pkg_list[0].obj, false);
} }
Export.Export(comp, filename); Exporter.Export(comp, filename);
} }
...@@ -65,8 +65,7 @@ type T9 struct { ...@@ -65,8 +65,7 @@ type T9 struct {
f *func(x, y *T9) *T9; f *func(x, y *T9) *T9;
} }
type T10; export type T11 struct {
type T11 struct {
p *T10; p *T10;
} }
...@@ -78,7 +77,6 @@ type T12 struct { ...@@ -78,7 +77,6 @@ type T12 struct {
p *T12 p *T12
} }
type I0 interface {} type I0 interface {}
type I1 interface { type I1 interface {
Do0(q *I0); Do0(q *I0);
...@@ -124,3 +122,9 @@ func (p *T4) m4(a int) (z T5, ok bool) { return; } ...@@ -124,3 +122,9 @@ func (p *T4) m4(a int) (z T5, ok bool) { return; }
func (p *T4) m5(a, b int, c float) (z T5, ok bool) { func (p *T4) m5(a, b int, c float) (z T5, ok bool) {
L: var x = a; L: var x = a;
} }
func f2() {
type T *T14;
}
type T14 int;
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package Exporter package Exporter
import Platform "platform"
import Utils "utils" import Utils "utils"
import Globals "globals" import Globals "globals"
import Object "object" import Object "object"
...@@ -248,7 +249,7 @@ func (E *Exporter) Export(comp* Globals.Compilation, file_name string) { ...@@ -248,7 +249,7 @@ func (E *Exporter) Export(comp* Globals.Compilation, file_name string) {
} }
// write magic bits // write magic bits
magic := Globals.MAGIC_obj_file; // TODO remove once len(constant) works magic := Platform.MAGIC_obj_file; // TODO remove once len(constant) works
for i := 0; i < len(magic); i++ { for i := 0; i < len(magic); i++ {
E.WriteByte(magic[i]); E.WriteByte(magic[i]);
} }
...@@ -283,7 +284,51 @@ func (E *Exporter) Export(comp* Globals.Compilation, file_name string) { ...@@ -283,7 +284,51 @@ func (E *Exporter) Export(comp* Globals.Compilation, file_name string) {
} }
func (E *Exporter) Export2(comp* Globals.Compilation) string {
E.comp = comp;
E.debug = comp.flags.debug;
E.buf_pos = 0;
E.pkg_ref = 0;
E.type_ref = 0;
// write magic bits
magic := Platform.MAGIC_obj_file; // TODO remove once len(constant) works
for i := 0; i < len(magic); i++ {
E.WriteByte(magic[i]);
}
// Predeclared types are "pre-exported".
// TODO run the loop below only in debug mode
{ i := 0;
for p := Universe.types.first; p != nil; p = p.next {
if p.typ.ref != i {
panic "incorrect ref for predeclared type";
}
i++;
}
}
E.type_ref = Universe.types.len_;
// export package 0
pkg := comp.pkg_list[0];
E.WritePackage(pkg);
E.WriteScope(pkg.scope);
if E.debug {
print "\n(", E.buf_pos, " bytes)\n";
}
return string(E.buf)[0 : E.buf_pos];
}
export func Export(comp* Globals.Compilation, pkg_name string) { export func Export(comp* Globals.Compilation, pkg_name string) {
var E Exporter; var E Exporter;
(&E).Export(comp, Utils.TrimExt(Utils.BaseName(pkg_name), Globals.src_file_ext) + Globals.obj_file_ext); (&E).Export(comp, Utils.TrimExt(Utils.BaseName(pkg_name), Platform.src_file_ext) + Platform.obj_file_ext);
}
export func Export2(comp* Globals.Compilation) string {
var E Exporter;
return (&E).Export2(comp);
} }
...@@ -5,18 +5,6 @@ ...@@ -5,18 +5,6 @@
package Globals package Globals
// ----------------------------------------------------------------------------
// Constants
export const (
MAGIC_obj_file = "/*go.7*/"; // anything, really
src_file_ext = ".go";
obj_file_ext = ".7";
)
// ----------------------------------------------------------------------------
// The following types should really be in their respective files // The following types should really be in their respective files
// (object.go, type.go, scope.go, package.go, compilation.go, etc.) but // (object.go, type.go, scope.go, package.go, compilation.go, etc.) but
// they refer to each other and we don't know how to handle forward // they refer to each other and we don't know how to handle forward
...@@ -44,7 +32,7 @@ export type Type struct { ...@@ -44,7 +32,7 @@ export type Type struct {
obj *Object; // primary type object or NULL obj *Object; // primary type object or NULL
aux *Type; // alias base type or map key aux *Type; // alias base type or map key
elt *Type; // aliases, arrays, maps, channels, pointers elt *Type; // aliases, arrays, maps, channels, pointers
scope *Scope; // structs, interfaces, functions scope *Scope; // forwards, structs, interfaces, functions
} }
...@@ -72,7 +60,7 @@ export type Scope struct { ...@@ -72,7 +60,7 @@ export type Scope struct {
export type Flags struct { export type Flags struct {
debug bool; debug bool;
object_filename string; object_file string;
update_packages bool; update_packages bool;
print_interface bool; print_interface bool;
verbosity uint; verbosity uint;
...@@ -86,13 +74,18 @@ export type Flags struct { ...@@ -86,13 +74,18 @@ export type Flags struct {
} }
export type Compilation struct { export type Environment struct {
// envionment
flags *Flags;
Error *func(comp *Compilation); // TODO complete this Error *func(comp *Compilation); // TODO complete this
Import *func(comp *Compilation, data string) *Package; Import *func(comp *Compilation, pkg_file string) *Package;
Export *func(comp *Compilation) string; Export *func(comp *Compilation) string;
Compile *func(flags *Flags, filename string); // TODO remove this eventually Compile *func(flags *Flags, env* Environment, file string);
}
export type Compilation struct {
// environment
flags *Flags;
env *Environment;
// TODO use open arrays eventually // TODO use open arrays eventually
pkg_list [256] *Package; // pkg_list[0] is the current package pkg_list [256] *Package; // pkg_list[0] is the current package
...@@ -128,7 +121,7 @@ type Elem struct { ...@@ -128,7 +121,7 @@ type Elem struct {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Creation // Creation
export var Universe_undef_t *Type // initialized by Universe to Universe.undef_t export var Universe_void_t *Type // initialized by Universe to Universe.void_t
export func NewObject(pos, kind int, ident string) *Object { export func NewObject(pos, kind int, ident string) *Object {
obj := new(Object); obj := new(Object);
...@@ -136,7 +129,7 @@ export func NewObject(pos, kind int, ident string) *Object { ...@@ -136,7 +129,7 @@ export func NewObject(pos, kind int, ident string) *Object {
obj.pos = pos; obj.pos = pos;
obj.kind = kind; obj.kind = kind;
obj.ident = ident; obj.ident = ident;
obj.typ = Universe_undef_t; obj.typ = Universe_void_t;
obj.pnolev = 0; obj.pnolev = 0;
return obj; return obj;
} }
......
...@@ -15,7 +15,7 @@ func PrintHelp() { ...@@ -15,7 +15,7 @@ func PrintHelp() {
"usage:\n" + "usage:\n" +
" go { flag } { file }\n" + " go { flag } { file }\n" +
" -d debug mode, additional self tests and prints\n" + " -d debug mode, additional self tests and prints\n" +
" -o filename explicit object filename\n" + " -o file explicit object file\n" +
" -r recursively update imported packages in current directory\n" + " -r recursively update imported packages in current directory\n" +
" -p print package interface\n" + " -p print package interface\n" +
" -v [0 .. 3] verbosity level\n" + " -v [0 .. 3] verbosity level\n" +
...@@ -53,7 +53,7 @@ func main() { ...@@ -53,7 +53,7 @@ func main() {
for arg != "" { for arg != "" {
switch arg { switch arg {
case "-d": flags.debug = true; case "-d": flags.debug = true;
case "-o": flags.object_filename = Next(); case "-o": flags.object_file = Next();
print "note: -o flag ignored at the moment\n"; print "note: -o flag ignored at the moment\n";
case "-r": flags.update_packages = true; case "-r": flags.update_packages = true;
case "-p": flags.print_interface = true; case "-p": flags.print_interface = true;
...@@ -81,8 +81,14 @@ func main() { ...@@ -81,8 +81,14 @@ func main() {
arg = Next(); arg = Next();
} }
// setup environment
env := new(Globals.Environment);
env.Import = &Compilation.Import;
env.Export = &Compilation.Export;
env.Compile = &Compilation.Compile;
// compile files // compile files
for p := files.first; p != nil; p = p.next { for p := files.first; p != nil; p = p.next {
Compilation.Compile(flags, p.str); Compilation.Compile(flags, env, p.str);
} }
} }
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package Importer package Importer
import Platform "platform"
import Utils "utils" import Utils "utils"
import Globals "globals" import Globals "globals"
import Object "object" import Object "object"
...@@ -128,6 +129,9 @@ func (I *Importer) ReadPackage() *Globals.Package { ...@@ -128,6 +129,9 @@ func (I *Importer) ReadPackage() *Globals.Package {
obj := Globals.NewObject(-1, Object.PACKAGE, ident); obj := Globals.NewObject(-1, Object.PACKAGE, ident);
pkg = Globals.NewPackage(file_name, obj, Globals.NewScope(nil)); pkg = Globals.NewPackage(file_name, obj, Globals.NewScope(nil));
I.comp.Insert(pkg); I.comp.Insert(pkg);
if I.comp.flags.verbosity > 1 {
print `import: implicitly adding package `, ident, ` "`, file_name, `" (pno = `, obj.pnolev, ")\n";
}
} else if key != pkg.key { } else if key != pkg.key {
// the package was imported before but the package // the package was imported before but the package
// key has changed // key has changed
...@@ -264,84 +268,18 @@ func (I *Importer) ReadObject() *Globals.Object { ...@@ -264,84 +268,18 @@ func (I *Importer) ReadObject() *Globals.Object {
} }
func ReadObjectFile(filename string) (data string, ok bool) { func (I *Importer) Import(comp* Globals.Compilation, data string) *Globals.Package {
data, ok = sys.readfile(filename + Globals.obj_file_ext);
magic := Globals.MAGIC_obj_file; // TODO remove once len(constant) works
if ok && len(data) >= len(magic) && data[0 : len(magic)] == magic {
return data, ok;
}
return "", false;
}
func ReadSourceFile(filename string) (data string, ok bool) {
data, ok = sys.readfile(filename + Globals.src_file_ext);
return data, ok;
}
func ReadImport(comp* Globals.Compilation, filename string, update bool) (data string, ok bool) {
if filename == "" {
panic "illegal package file name";
}
// see if it just works
data, ok = ReadObjectFile(filename);
if ok {
return data, ok;
}
if filename[0] == '/' {
// absolute path
panic `don't know how to handle absolute import file path "` + filename + `"`;
}
// relative path
// try relative to the $GOROOT/pkg directory
std_filename := Utils.GOROOT + "/pkg/" + filename;
data, ok = ReadObjectFile(std_filename);
if ok {
return data, ok;
}
if !update {
return "", false;
}
// TODO BIG HACK - fix this!
// look for a src file
// see if it just works
data, ok = ReadSourceFile(filename);
if ok {
comp.Compile(comp.flags, filename + Globals.src_file_ext);
data, ok = ReadImport(comp, filename, false);
if ok {
return data, ok;
}
}
return "", false;
}
func (I *Importer) Import(comp* Globals.Compilation, file_name string) *Globals.Package {
I.comp = comp; I.comp = comp;
I.debug = comp.flags.debug; I.debug = comp.flags.debug;
I.buf = ""; I.buf = data;
I.buf_pos = 0; I.buf_pos = 0;
I.pkg_ref = 0; I.pkg_ref = 0;
I.type_ref = 0; I.type_ref = 0;
if I.debug { // check magic bits
print "importing from ", file_name, "\n"; if !Utils.Contains(data, Platform.MAGIC_obj_file, 0) {
}
// read file and check magic bits
buf, ok := ReadImport(comp, file_name, comp.flags.update_packages);
if !ok {
return nil; return nil;
} }
I.buf = buf;
// Predeclared types are "pre-imported". // Predeclared types are "pre-imported".
for p := Universe.types.first; p != nil; p = p.next { for p := Universe.types.first; p != nil; p = p.next {
...@@ -364,7 +302,8 @@ func (I *Importer) Import(comp* Globals.Compilation, file_name string) *Globals. ...@@ -364,7 +302,8 @@ func (I *Importer) Import(comp* Globals.Compilation, file_name string) *Globals.
} }
export func Import(comp* Globals.Compilation, pkg_name string) *Globals.Package { export func Import(comp *Globals.Compilation, data string) *Globals.Package {
var I Importer; var I Importer;
return (&I).Import(comp, pkg_name); pkg := (&I).Import(comp, data);
return pkg;
} }
This diff is collapsed.
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package Platform
// ----------------------------------------------------------------------------
// Environment
export var
GOARCH,
GOOS,
GOROOT,
USER string;
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: trim "="
}
}
return "";
}
func init() {
GOARCH = GetEnv("GOARCH");
GOOS = GetEnv("GOOS");
GOROOT = GetEnv("GOROOT");
USER = GetEnv("USER");
}
// ----------------------------------------------------------------------------
// I/O
export const (
MAGIC_obj_file = "@gri-go.7@v0"; // make it clear thar it cannot be a source file
src_file_ext = ".go";
obj_file_ext = ".7";
)
export func ReadObjectFile(filename string) (data string, ok bool) {
data, ok = sys.readfile(filename + obj_file_ext);
magic := MAGIC_obj_file; // TODO remove once len(constant) works
if ok && len(data) >= len(magic) && data[0 : len(magic)] == magic {
return data, ok;
}
return "", false;
}
export func ReadSourceFile(filename string) (data string, ok bool) {
data, ok = sys.readfile(filename + src_file_ext);
return data, ok;
}
...@@ -186,8 +186,11 @@ func (P *Printer) PrintObject(obj *Globals.Object) { ...@@ -186,8 +186,11 @@ func (P *Printer) PrintObject(obj *Globals.Object) {
func (P *Printer) PrintTypeStruct(typ *Globals.Type) { func (P *Printer) PrintTypeStruct(typ *Globals.Type) {
switch typ.form { switch typ.form {
case Type.UNDEF: case Type.VOID:
print "<undef type>"; print "void";
case Type.FORWARD:
print "<forward type>";
case Type.BAD: case Type.BAD:
print "<bad type>"; print "<bad type>";
......
...@@ -4,8 +4,10 @@ ...@@ -4,8 +4,10 @@
package Scanner package Scanner
import Platform "platform"
import Utils "utils" import Utils "utils"
export const ( export const (
ILLEGAL = iota; ILLEGAL = iota;
EOF; EOF;
...@@ -223,7 +225,7 @@ func init() { ...@@ -223,7 +225,7 @@ func init() {
} }
// Provide column information in error messages for gri only... // Provide column information in error messages for gri only...
VerboseMsgs = Utils.USER == "gri"; VerboseMsgs = Platform.USER == "gri";
} }
...@@ -291,7 +293,7 @@ func (S *Scanner) Next() { ...@@ -291,7 +293,7 @@ func (S *Scanner) Next() {
Bad = 0xFFFD; // Runeerror Bad = 0xFFFD; // Runeerror
); );
src := S.src; // TODO only needed because of 6g bug src := S.src;
lim := len(src); lim := len(src);
pos := S.pos; pos := S.pos;
...@@ -425,38 +427,6 @@ func (S *Scanner) Open(filename, src string) { ...@@ -425,38 +427,6 @@ func (S *Scanner) Open(filename, src string) {
} }
// TODO this needs to go elsewhere
func IntString(x, base int) string {
neg := false;
if x < 0 {
x = -x;
if x < 0 {
panic "smallest int not handled";
}
neg = true;
}
hex := "0123456789ABCDEF";
var buf [16] byte;
i := 0;
for x > 0 || i == 0 {
buf[i] = hex[x % base];
x /= base;
i++;
}
s := "";
if neg {
s = "-";
}
for i > 0 {
i--;
s = s + string(int(buf[i]));
}
return s;
}
func CharString(ch int) string { func CharString(ch int) string {
s := string(ch); s := string(ch);
switch ch { switch ch {
...@@ -470,7 +440,7 @@ func CharString(ch int) string { ...@@ -470,7 +440,7 @@ func CharString(ch int) string {
case '\\': s = `\\`; case '\\': s = `\\`;
case '\'': s = `\'`; case '\'': s = `\'`;
} }
return "'" + s + "' (U+" + IntString(ch, 16) + ")"; return "'" + s + "' (U+" + Utils.IntToString(ch, 16) + ")";
} }
......
...@@ -10,11 +10,28 @@ import Object "object" ...@@ -10,11 +10,28 @@ import Object "object"
export const /* form */ ( export const /* form */ (
// internal types // internal types
UNDEF = iota; VOID; BAD; NIL; // VOID types are used when we don't have a type.
VOID = iota;
// BAD types are compatible with any type and don't cause further errors.
// They are introduced only as a result of an error in the source code. A
// correct program cannot have BAD types.
BAD;
// FORWARD types are forward-declared (incomplete) types. They can only
// be used as element types of pointer types and must be resolved before
// their internals are accessible.
FORWARD;
// The type of nil.
NIL;
// basic types // basic types
BOOL; UINT; INT; FLOAT; STRING; INTEGER; BOOL; UINT; INT; FLOAT; STRING; INTEGER;
// 'any' type
// 'any' type // TODO this should go away eventually
ANY; ANY;
// composite types // composite types
ALIAS; ARRAY; STRUCT; INTERFACE; MAP; CHANNEL; FUNCTION; POINTER; REFERENCE; ALIAS; ARRAY; STRUCT; INTERFACE; MAP; CHANNEL; FUNCTION; POINTER; REFERENCE;
) )
...@@ -33,9 +50,9 @@ export const /* flag */ ( ...@@ -33,9 +50,9 @@ export const /* flag */ (
export func FormStr(form int) string { export func FormStr(form int) string {
switch form { switch form {
case UNDEF: return "UNDEF";
case VOID: return "VOID"; case VOID: return "VOID";
case BAD: return "BAD"; case BAD: return "BAD";
case FORWARD: return "FORWARD";
case NIL: return "NIL"; case NIL: return "NIL";
case BOOL: return "BOOL"; case BOOL: return "BOOL";
case UINT: return "UINT"; case UINT: return "UINT";
...@@ -74,7 +91,7 @@ func Equal0(x, y *Globals.Type) bool { ...@@ -74,7 +91,7 @@ func Equal0(x, y *Globals.Type) bool {
} }
switch x.form { switch x.form {
case UNDEF, BAD: case FORWARD, BAD:
break; break;
case NIL, BOOL, STRING, ANY: case NIL, BOOL, STRING, ANY:
......
...@@ -14,7 +14,7 @@ export var ( ...@@ -14,7 +14,7 @@ export var (
types *Globals.List; types *Globals.List;
// internal types // internal types
undef_t, void_t,
bad_t, bad_t,
nil_t, nil_t,
...@@ -93,8 +93,8 @@ func init() { ...@@ -93,8 +93,8 @@ func init() {
types = Globals.NewList(); types = Globals.NewList();
// Interal types // Interal types
undef_t = Globals.NewType(Type.UNDEF); void_t = Globals.NewType(Type.VOID);
Globals.Universe_undef_t = undef_t; Globals.Universe_void_t = void_t;
bad_t = Globals.NewType(Type.BAD); bad_t = Globals.NewType(Type.BAD);
nil_t = DeclType(Type.NIL, "nil", 8); nil_t = DeclType(Type.NIL, "nil", 8);
......
...@@ -5,34 +5,6 @@ ...@@ -5,34 +5,6 @@
package Utils package Utils
// Environment
export var
GOARCH,
GOOS,
GOROOT,
USER string;
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: trim "="
}
}
return "";
}
func init() {
GOARCH = GetEnv("GOARCH");
GOOS = GetEnv("GOOS");
GOROOT = GetEnv("GOROOT");
USER = GetEnv("USER");
}
export func BaseName(s string) string { export func BaseName(s string) string {
// TODO this is not correct for non-ASCII strings! // TODO this is not correct for non-ASCII strings!
i := len(s) - 1; i := len(s) - 1;
...@@ -46,6 +18,12 @@ export func BaseName(s string) string { ...@@ -46,6 +18,12 @@ export func BaseName(s string) string {
} }
export func Contains(s, sub string, pos int) bool {
end := pos + len(sub);
return pos >= 0 && end <= len(s) && s[pos : end] == sub;
}
export func TrimExt(s, ext string) string { export func TrimExt(s, ext string) string {
i := len(s) - len(ext); i := len(s) - len(ext);
if i >= 0 && s[i : len(s)] == ext { if i >= 0 && s[i : len(s)] == ext {
...@@ -53,3 +31,33 @@ export func TrimExt(s, ext string) string { ...@@ -53,3 +31,33 @@ export func TrimExt(s, ext string) string {
} }
return s; return s;
} }
export func IntToString(x, base int) string {
x0 := x;
if x < 0 {
x = -x;
if x < 0 {
panic "smallest int not handled";
}
} else if x == 0 {
return "0";
}
// x > 0
hex := "0123456789ABCDEF";
var buf [32] byte;
i := len(buf);
for x > 0 {
i--;
buf[i] = hex[x % base];
x /= base;
}
if x0 < 0 {
i--;
buf[i] = '-';
}
return string(buf)[i : len(buf)];
}
...@@ -45,7 +45,12 @@ func (V *Verifier) VerifyType(typ *Globals.Type) { ...@@ -45,7 +45,12 @@ func (V *Verifier) VerifyType(typ *Globals.Type) {
} }
switch typ.form { switch typ.form {
case Type.UNDEF: // for now - remove eventually case Type.VOID:
break; // TODO for now - remove eventually
case Type.FORWARD:
if typ.scope == nil {
Error("forward types must have a scope");
}
break; break;
case Type.NIL: case Type.NIL:
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