diff --git a/usr/gri/pretty/Makefile b/usr/gri/pretty/Makefile
index cfc2bb132c7502f020e6e995a39922ed78300f36..1386c0cd582c21099586bde26a78528bca3a31e1 100644
--- a/usr/gri/pretty/Makefile
+++ b/usr/gri/pretty/Makefile
@@ -29,15 +29,15 @@ pretty.6:	 platform.6 printer.6 compilation.6
 
 compilation.6:	 platform.6 scanner.6 parser.6 ast.6 typechecker.6
 
-ast.6:	 scanner.6
+ast.6:	 scanner.6 globals.6 type.6
 
 scanner.6:	 utils.6
 
-parser.6:	 scanner.6 ast.6
+parser.6:	 scanner.6 ast.6 globals.6 object.6 type.6
 
 platform.6:	 utils.6
 
-printer.6:	 scanner.6 ast.6
+printer.6:	 scanner.6 ast.6 globals.6 object.6 type.6
 
 typechecker.6:	ast.6 universe.6 globals.6 type.6
 
diff --git a/usr/gri/pretty/ast.go b/usr/gri/pretty/ast.go
index 5e40a61cc93a33acf826991b2d912531e47dbbe2..ad1edaeb236b8b2794b7553755d0146466afcc56 100644
--- a/usr/gri/pretty/ast.go
+++ b/usr/gri/pretty/ast.go
@@ -6,12 +6,13 @@ package AST
 
 import (
 	"array";
+	Globals "globals";
+	Object "object";
 	Scanner "scanner";
 )
 
 
 type (
-	Object struct;
 	Type struct;
 	Expr struct;
 	Stat struct;
@@ -28,39 +29,16 @@ export type Node struct {
 }
 
 
-// ----------------------------------------------------------------------------
-// Objects represent declared language objects, such as a const, type, var;
-// but also anonymous objects such as type and other literals.
-
-export type Object struct {
-	Node;
-	lit string;  // identifiers and literals
-	typ *Type;
-	val *Expr;
-}
-
-
-export func NewObject(pos, tok int, lit string) *Object {
-	obj := new(Object);
-	obj.pos, obj.tok = pos, tok;
-	obj.lit = lit;
-	obj.typ = nil;  // Universe::void_typ
-	return obj;
-}
-
-
 // ----------------------------------------------------------------------------
 // Expressions
 
 export type Expr struct {
 	Node;
 	x, y *Expr;  // binary (x, y) and unary (y) expressions
-	obj *Object;
-	
-	// TODO find a more space efficient way to hold these
-	s string;  // identifiers and literals
+	obj *Globals.Object;
+
+	// TODO this one should go as well
 	t *Type;  // type expressions, function literal types
-	block *array.Array; end int;  // stats for function literals
 }
 
 
@@ -86,9 +64,9 @@ export func NewExpr(pos, tok int, x, y *Expr) *Expr {
 }
 
 
-export func NewLit(pos, tok int, s string) *Expr {
+export func NewLit(pos, tok int, obj *Globals.Object) *Expr {
 	e := new(Expr);
-	e.pos, e.tok, e.s = pos, tok, s;
+	e.pos, e.tok, e.obj = pos, tok, obj;
 	return e;
 }
 
diff --git a/usr/gri/pretty/compilation.go b/usr/gri/pretty/compilation.go
index ce1923aa0b65b9ead8d7dbe1cce7797e4d245505..491b41c33ce33a902410710bb87739a6c5266e2f 100644
--- a/usr/gri/pretty/compilation.go
+++ b/usr/gri/pretty/compilation.go
@@ -171,7 +171,7 @@ func AddDeps(globalset map [string] bool, wset *array.Array, src_file string, fl
 			for i := 0; i < nimports; i++ {
 				decl := prog.decls.At(i).(*AST.Decl);
 				assert(decl.tok == Scanner.IMPORT && decl.val.tok == Scanner.STRING);
-				src := decl.val.s;
+				src := decl.val.obj.ident;
 				src = src[1 : len(src) - 1];  // strip "'s
 
 				// ignore files when they are seen a 2nd time
diff --git a/usr/gri/pretty/globals.go b/usr/gri/pretty/globals.go
index 25a8702f15be1b0ba38883d4f7f33799c4f697eb..199a8c91e233704f2a855cf612c14691af9293b8 100644
--- a/usr/gri/pretty/globals.go
+++ b/usr/gri/pretty/globals.go
@@ -5,6 +5,8 @@
 package Globals
 
 
+import "array"
+
 // The following types should really be in their respective files
 // (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
@@ -29,6 +31,9 @@ export type Object struct {
 	ident string;
 	typ *Type;  // nil for packages
 	pnolev int;  // >= 0: package no., <= 0: function nesting level, 0: global level
+	
+	// attached values
+	block *array.Array; end int;  // stats for function literals; end of block pos
 }
 
 
diff --git a/usr/gri/pretty/object.go b/usr/gri/pretty/object.go
index 220f4c8d8b4a401a6e8bfb4e4075c8b5885eb65d..b09e563d442dbf4e5ebb605b6234afe69606b220 100755
--- a/usr/gri/pretty/object.go
+++ b/usr/gri/pretty/object.go
@@ -9,6 +9,7 @@ import Globals "globals"
 
 export const /* kind */ (
 	BAD = iota;  // error handling
+	NONE;  // kind unknown
 	CONST; TYPE; VAR; FIELD; FUNC; BUILTIN; PACKAGE; LABEL;
 	END;  // end of scope (import/export only)
 )
@@ -22,6 +23,7 @@ export const /* kind */ (
 export func KindStr(kind int) string {
 	switch kind {
 	case BAD: return "BAD";
+	case NONE: return "NONE";
 	case CONST: return "CONST";
 	case TYPE: return "TYPE";
 	case VAR: return "VAR";
diff --git a/usr/gri/pretty/parser.go b/usr/gri/pretty/parser.go
index 0bca27867d675370e7842ced5ee2e13035f66314..b77de1493e9d0b27c8c6091a2d589e78af84e303 100644
--- a/usr/gri/pretty/parser.go
+++ b/usr/gri/pretty/parser.go
@@ -5,6 +5,8 @@
 package Parser
 
 import "array"
+import Globals "globals"
+import Object "object"
 import Scanner "scanner"
 import AST "ast"
 
@@ -148,7 +150,8 @@ func ExprType(x *AST.Expr) *AST.Type {
 func (P *Parser) NoType(x *AST.Expr) *AST.Expr {
 	if x != nil && x.tok == Scanner.TYPE {
 		P.Error(x.pos, "expected expression, found type");
-		x = AST.NewLit(x.pos, Scanner.INT, "");
+		val := Globals.NewObject(x.pos, Object.NONE, "0");
+		x = AST.NewLit(x.pos, Scanner.INT, val);
 	}
 	return x;
 }
@@ -173,10 +176,11 @@ func (P *Parser) ParseIdent() *AST.Expr {
 
 	x := AST.BadExpr;
 	if P.tok == Scanner.IDENT {
-		x = AST.NewLit(P.pos, Scanner.IDENT, P.val);
+		obj := Globals.NewObject(P.pos, Object.NONE, P.val);
+		x = AST.NewLit(P.pos, Scanner.IDENT, obj);
 		if P.verbose {
 			P.PrintIndent();
-			print("Ident = \"", x.s, "\"\n");
+			print("Ident = \"", x.obj.ident, "\"\n");
 		}
 		P.Next();
 	} else {
@@ -658,12 +662,13 @@ func (P *Parser) ParseExpressionList() *AST.Expr {
 func (P *Parser) ParseFunctionLit() *AST.Expr {
 	P.Trace("FunctionLit");
 
-	x := AST.NewLit(P.pos, Scanner.FUNC, "");
+	val := Globals.NewObject(P.pos, Object.NONE, "");
+	x := AST.NewLit(P.pos, Scanner.FUNC, val);
 	P.Expect(Scanner.FUNC);
 	x.t = P.ParseFunctionType();
 	P.expr_lev++;
 	P.scope_lev++;
-	x.block, x.end = P.ParseBlock();
+	val.block, val.end = P.ParseBlock();
 	P.scope_lev--;
 	P.expr_lev--;
 
@@ -712,11 +717,14 @@ func (P *Parser) ParseOperand() *AST.Expr {
 		P.Expect(Scanner.RPAREN);
 
 	case Scanner.INT, Scanner.FLOAT, Scanner.STRING:
-		x = AST.NewLit(P.pos, P.tok, P.val);
+		val := Globals.NewObject(P.pos, Object.NONE, P.val);
+		x = AST.NewLit(P.pos, P.tok, val);
 		P.Next();
 		if x.tok == Scanner.STRING {
+			// TODO should remember the list instead of
+			//      concatenate the strings here
 			for ; P.tok == Scanner.STRING; P.Next() {
-				x.s += P.val;
+				x.obj.ident += P.val;
 			}
 		}
 
@@ -783,7 +791,7 @@ func (P *Parser) ParseCall(x0 *AST.Expr) *AST.Expr {
 	if P.tok != Scanner.RPAREN {
 		P.expr_lev++;
 		var t *AST.Type;
-		if x0.tok == Scanner.IDENT && (x0.s == "new" || x0.s == "make") {
+		if x0.tok == Scanner.IDENT && (x0.obj.ident == "new" || x0.obj.ident == "make") {
 			// heuristic: assume it's a new(T) or make(T, ...) call, try to parse a type
 			t = P.TryType();
 		}
@@ -1367,7 +1375,8 @@ func (P *Parser) ParseImportSpec(pos int) *AST.Decl {
 
 	if P.tok == Scanner.STRING {
 		// TODO eventually the scanner should strip the quotes
-		d.val = AST.NewLit(P.pos, Scanner.STRING, P.val);
+		val := Globals.NewObject(P.pos, Object.NONE, P.val);
+		d.val = AST.NewLit(P.pos, Scanner.STRING, val);
 		P.Next();
 	} else {
 		P.Expect(Scanner.STRING);  // use Expect() error handling
diff --git a/usr/gri/pretty/pretty.go b/usr/gri/pretty/pretty.go
index 80edbfcc49a5cd2d13954c0f7dfd629274913fb0..4d36bbe4f1bfe2e2eec2c0422c2711b670af9d06 100644
--- a/usr/gri/pretty/pretty.go
+++ b/usr/gri/pretty/pretty.go
@@ -4,10 +4,12 @@
 
 package main
 
-import Flag "flag"
-import Platform "platform"
-import Printer "printer"
-import Compilation "compilation"
+import (
+	Flag "flag";
+	Platform "platform";
+	Printer "printer";
+	Compilation "compilation";
+)
 
 
 var (
@@ -15,7 +17,8 @@ var (
 	silent = Flag.Bool("s", false, nil, "silent mode: no pretty print output");
 	verbose = Flag.Bool("v", false, &flags.verbose, "verbose mode: trace parsing");
 	sixg = Flag.Bool("6g", true, &flags.sixg, "6g compatibility mode");
-	deps = Flag.Bool("d", false, &flags.deps, "print dependency information only");
+	//TODO fix this code again
+	//deps = Flag.Bool("d", false, &flags.deps, "print dependency information only");
 	columns = Flag.Bool("columns", Platform.USER == "gri", &flags.columns, "print column info in error messages");
 	testmode = Flag.Bool("t", false, &flags.testmode, "test mode: interprets /* ERROR */ and /* SYNC */ comments");
 	tokenchan = Flag.Bool("token_chan", false, &flags.tokenchan, "use token channel for scanner-parser connection");
@@ -40,7 +43,7 @@ func main() {
 	for i := 0; i < Flag.NArg(); i++ {
 		src_file := Flag.Arg(i);
 
-		if flags.deps {
+		if false /* DISABLED flags.deps */ {
 			Compilation.ComputeDeps(src_file, &flags);
 			
 		} else {
diff --git a/usr/gri/pretty/printer.go b/usr/gri/pretty/printer.go
index cbfdc5fc80a279ab55f2c99a3355a85441b91ff9..10dc45d3d80c4882318adcf8321f19b645404241 100644
--- a/usr/gri/pretty/printer.go
+++ b/usr/gri/pretty/printer.go
@@ -11,6 +11,8 @@ import (
 	"tabwriter";
 	"flag";
 	"fmt";
+	Globals "globals";
+	Object "object";
 	Scanner "scanner";
 	AST "ast";
 )
@@ -363,12 +365,12 @@ func (P *Printer) HtmlEpilogue() {
 }
 
 
-func (P *Printer) HtmlIdentifier(pos int, ident string) {
+func (P *Printer) HtmlIdentifier(pos int, obj *Globals.Object) {
 	if html.BVal() {
 		// no need to HtmlEscape ident
-		P.TaggedString(pos, `<a href="#` + ident + `">`, ident, `</a>`);
+		P.TaggedString(pos, `<a href="#` + obj.ident + `">`, obj.ident, `</a>`);
 	} else {
-		P.String(pos, ident);
+		P.String(pos, obj.ident);
 	}
 }
 
@@ -515,17 +517,17 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
 		P.Type(x.t);
 
 	case Scanner.IDENT:
-		P.HtmlIdentifier(x.pos, x.s);
+		P.HtmlIdentifier(x.pos, x.obj);
 	
 	case Scanner.INT, Scanner.STRING, Scanner.FLOAT:
 		// literal
-		P.String(x.pos, x.s);
+		P.String(x.pos, x.obj.ident);
 
 	case Scanner.FUNC:
 		// function literal
 		P.String(x.pos, "func");
 		P.Type(x.t);
-		P.Block(0, x.block, x.end, true);
+		P.Block(0, x.obj.block, x.obj.end, true);
 		P.newlines = 0;
 
 	case Scanner.COMMA:
diff --git a/usr/gri/pretty/typechecker.go b/usr/gri/pretty/typechecker.go
index 4b0c6e48a02c9ff623e07d02a9ef9095b2dd4a77..1b27942dcee22b34caa289b341595e7c83d7d0a4 100644
--- a/usr/gri/pretty/typechecker.go
+++ b/usr/gri/pretty/typechecker.go
@@ -103,7 +103,7 @@ func (s *State) DeclareIdent(ident *AST.Expr, kind int, typ *AST.Type) {
 	// ident is either a comma-separated list or a single ident
 	switch ident.tok {
 	case Scanner.IDENT:
-		obj := Globals.NewObject(ident.pos, kind, ident.s);
+		obj := Globals.NewObject(ident.pos, kind, ident.obj.ident);
 		s.Declare(obj);
 	case Scanner.COMMA:
 		s.DeclareIdent(ident.x, kind, typ);
@@ -149,7 +149,7 @@ func (s *State) CheckDeclaration(d *AST.Decl) {
 		case Scanner.TYPE:
 			assert(d.ident.tok == Scanner.IDENT);
 			// types may be forward-declared
-			obj := s.Lookup(d.ident.s);
+			obj := s.Lookup(d.ident.obj.ident);
 			if obj != nil {
 				// TODO check if proper forward-declaration
 
@@ -164,7 +164,7 @@ func (s *State) CheckDeclaration(d *AST.Decl) {
 				// TODO
 			} else {
 				// functions may be forward-declared
-				obj := s.Lookup(d.ident.s);
+				obj := s.Lookup(d.ident.obj.ident);
 				if obj != nil {
 				  // TODO check if proper forward-declaration