summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2009-06-02 17:18:27 -0700
committerRobert Griesemer <gri@golang.org>2009-06-02 17:18:27 -0700
commite800c67da3d9211159888bfc4005246166719d73 (patch)
treee9a1f371ad1bd0cc866cb7b91d32c83046e2e2f3 /src
parentcc1ec4adad8c2671b71dba4cd7eba47d0d62d84d (diff)
downloadgolang-e800c67da3d9211159888bfc4005246166719d73.tar.gz
- renamed format -> datafmt
- factored out datafmt-specifics from pretty to ast R=rsc DELTA=3580 (1810 added, 1763 deleted, 7 changed) OCL=29770 CL=29774
Diffstat (limited to 'src')
-rw-r--r--src/lib/Make.deps4
-rw-r--r--src/lib/Makefile4
-rw-r--r--src/lib/datafmt/Makefile (renamed from src/lib/format/Makefile)16
-rw-r--r--src/lib/datafmt/datafmt.go (renamed from src/lib/format/format.go)4
-rw-r--r--src/lib/datafmt/datafmt_test.go (renamed from src/lib/format/format_test.go)49
-rw-r--r--src/lib/datafmt/parser.go (renamed from src/lib/format/parser.go)4
-rw-r--r--src/lib/go/ast/Makefile10
-rw-r--r--src/lib/go/ast/format.go123
8 files changed, 174 insertions, 40 deletions
diff --git a/src/lib/Make.deps b/src/lib/Make.deps
index 4a1805f4c..12f086291 100644
--- a/src/lib/Make.deps
+++ b/src/lib/Make.deps
@@ -6,12 +6,12 @@ crypto/block.install: fmt.install io.install os.install
crypto/hmac.install: crypto/md5.install crypto/sha1.install hash.install os.install
crypto/md5.install: hash.install os.install
crypto/sha1.install: hash.install os.install
+datafmt.install: container/vector.install fmt.install go/scanner.install go/token.install io.install os.install reflect.install runtime.install strconv.install strings.install
exec.install: os.install strings.install
exvar.install: fmt.install http.install io.install log.install strconv.install sync.install
flag.install: fmt.install os.install strconv.install
fmt.install: io.install os.install reflect.install strconv.install utf8.install
-format.install: container/vector.install flag.install fmt.install go/scanner.install go/token.install io.install os.install reflect.install runtime.install strconv.install strings.install
-go/ast.install: go/token.install unicode.install utf8.install
+go/ast.install: datafmt.install go/token.install io.install os.install unicode.install utf8.install
go/doc.install: container/vector.install fmt.install go/ast.install go/token.install io.install once.install regexp.install sort.install strings.install template.install
go/parser.install: container/vector.install fmt.install go/ast.install go/scanner.install go/token.install io.install os.install
go/scanner.install: go/token.install strconv.install unicode.install utf8.install
diff --git a/src/lib/Makefile b/src/lib/Makefile
index d0658605e..3bce7d639 100644
--- a/src/lib/Makefile
+++ b/src/lib/Makefile
@@ -22,11 +22,11 @@ DIRS=\
crypto/hmac\
crypto/md5\
crypto/sha1\
+ datafmt\
exec\
exvar\
flag\
fmt\
- format\
go/ast\
go/doc\
go/parser\
@@ -70,11 +70,11 @@ TEST=\
crypto/block\
crypto/md5\
crypto/sha1\
+ datafmt\
exec\
exvar\
flag\
fmt\
- format\
go/parser\
go/scanner\
hash/adler32\
diff --git a/src/lib/format/Makefile b/src/lib/datafmt/Makefile
index 597933241..494b11ef9 100644
--- a/src/lib/format/Makefile
+++ b/src/lib/datafmt/Makefile
@@ -40,37 +40,37 @@ coverage: packages
$(AS) $*.s
O1=\
- format.$O\
+ datafmt.$O\
O2=\
parser.$O\
phases: a1 a2
-_obj$D/format.a: phases
+_obj$D/datafmt.a: phases
a1: $(O1)
- $(AR) grc _obj$D/format.a format.$O
+ $(AR) grc _obj$D/datafmt.a datafmt.$O
rm -f $(O1)
a2: $(O2)
- $(AR) grc _obj$D/format.a parser.$O
+ $(AR) grc _obj$D/datafmt.a parser.$O
rm -f $(O2)
newpkg: clean
mkdir -p _obj$D
- $(AR) grc _obj$D/format.a
+ $(AR) grc _obj$D/datafmt.a
$(O1): newpkg
$(O2): a1
$(O3): a2
nuke: clean
- rm -f $(GOROOT)/pkg$D/format.a
+ rm -f $(GOROOT)/pkg$D/datafmt.a
-packages: _obj$D/format.a
+packages: _obj$D/datafmt.a
install: packages
test -d $(GOROOT)/pkg && mkdir -p $(GOROOT)/pkg$D
- cp _obj$D/format.a $(GOROOT)/pkg$D/format.a
+ cp _obj$D/datafmt.a $(GOROOT)/pkg$D/datafmt.a
diff --git a/src/lib/format/format.go b/src/lib/datafmt/datafmt.go
index 392a9d0f0..baeb3ac41 100644
--- a/src/lib/format/format.go
+++ b/src/lib/datafmt/datafmt.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-/* The format package implements syntax-directed, type-driven formatting
+/* The datafmt package implements syntax-directed, type-driven formatting
of arbitrary data structures. Formatting a data structure consists of
two phases: first, a parser reads a format specification and builds a
"compiled" format. Then, the format can be applied repeatedly to
@@ -200,7 +200,7 @@
will format an argument list by printing each one in its default format,
separated by a comma and a space.
*/
-package format
+package datafmt
import (
"container/vector";
diff --git a/src/lib/format/format_test.go b/src/lib/datafmt/datafmt_test.go
index 92e0d0ea5..fcacc80f1 100644
--- a/src/lib/format/format_test.go
+++ b/src/lib/datafmt/datafmt_test.go
@@ -2,28 +2,28 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package format
+package datafmt
import (
"fmt";
- "format";
+ "datafmt";
"io";
"os";
"testing";
)
-func parse(t *testing.T, form string, fmap format.FormatterMap) format.Format {
- f, err := format.Parse(io.StringBytes(form), fmap);
+func parse(t *testing.T, form string, fmap FormatterMap) Format {
+ f, err := Parse(io.StringBytes(form), fmap);
if err != nil {
- t.Errorf("Parse(%s): %v", err);
+ t.Errorf("Parse(%s): %v", form, err);
return nil;
}
return f;
}
-func verify(t *testing.T, f format.Format, expected string, args ...) {
+func verify(t *testing.T, f Format, expected string, args ...) {
if f == nil {
return; // allow other tests to run
}
@@ -37,7 +37,7 @@ func verify(t *testing.T, f format.Format, expected string, args ...) {
}
-func formatter(s *format.State, value interface{}, rule_name string) bool {
+func formatter(s *State, value interface{}, rule_name string) bool {
switch rule_name {
case "/":
fmt.Fprintf(s, "%d %d %d", s.Pos().Line, s.LinePos().Column, s.Pos().Column);
@@ -61,8 +61,8 @@ func formatter(s *format.State, value interface{}, rule_name string) bool {
func TestCustomFormatters(t *testing.T) {
- fmap0 := format.FormatterMap{ "/": formatter };
- fmap1 := format.FormatterMap{ "int": formatter, "blank": formatter, "nil": formatter };
+ fmap0 := FormatterMap{ "/": formatter };
+ fmap1 := FormatterMap{ "int": formatter, "blank": formatter, "nil": formatter };
f := parse(t, `int=`, fmap0);
verify(t, f, ``, 1, 2, 3);
@@ -91,6 +91,9 @@ func TestCustomFormatters(t *testing.T) {
func check(t *testing.T, form, expected string, args ...) {
f := parse(t, form, nil);
+ if f == nil {
+ return; // allow other tests to run
+ }
result := f.Sprint(args);
if result != expected {
t.Errorf(
@@ -227,9 +230,9 @@ type T1 struct {
}
const F1 =
- `format "format";`
+ `datafmt "datafmt";`
`int = "%d";`
- `format.T1 = "<" a ">";`
+ `datafmt.T1 = "<" a ">";`
func TestStruct1(t *testing.T) {
check(t, F1, "<42>", T1{42});
@@ -248,13 +251,13 @@ const F2a =
F1 +
`string = "%s";`
`ptr = *;`
- `format.T2 = s ["-" p "-"];`
+ `datafmt.T2 = s ["-" p "-"];`
const F2b =
F1 +
`string = "%s";`
`ptr = *;`
- `format.T2 = s ("-" p "-" | "empty");`;
+ `datafmt.T2 = s ("-" p "-" | "empty");`;
func TestStruct2(t *testing.T) {
check(t, F2a, "foo", T2{"foo", nil});
@@ -272,19 +275,19 @@ type T3 struct {
}
const F3a =
- `format "format";`
+ `datafmt "datafmt";`
`default = "%v";`
`array = *;`
- `format.T3 = s {" " a a / ","};`
+ `datafmt.T3 = s {" " a a / ","};`
const F3b =
- `format "format";`
+ `datafmt "datafmt";`
`int = "%d";`
`string = "%s";`
`array = *;`
`nil = ;`
`empty = *:nil;`
- `format.T3 = s [a:empty ": " {a / "-"}]`
+ `datafmt.T3 = s [a:empty ": " {a / "-"}]`
func TestStruct3(t *testing.T) {
check(t, F3a, "foo", T3{"foo", nil});
@@ -303,22 +306,22 @@ type T4 struct {
}
const F4a =
- `format "format";`
+ `datafmt "datafmt";`
`int = "%d";`
`ptr = *;`
`array = *;`
`nil = ;`
`empty = *:nil;`
- `format.T4 = "<" (x:empty x | "-") ">" `
+ `datafmt.T4 = "<" (x:empty x | "-") ">" `
const F4b =
- `format "format";`
+ `datafmt "datafmt";`
`int = "%d";`
`ptr = *;`
`array = *;`
`nil = ;`
`empty = *:nil;`
- `format.T4 = "<" (a:empty {a / ", "} | "-") ">" `
+ `datafmt.T4 = "<" (a:empty {a / ", "} | "-") ">" `
func TestStruct4(t *testing.T) {
x := 7;
@@ -338,11 +341,11 @@ type Point struct {
}
const FPoint =
- `format "format";`
+ `datafmt "datafmt";`
`int = "%d";`
`hexInt = "0x%x";`
`string = "---%s---";`
- `format.Point = name "{" x ", " y:hexInt "}";`
+ `datafmt.Point = name "{" x ", " y:hexInt "}";`
func TestStructPoint(t *testing.T) {
p := Point{"foo", 3, 15};
diff --git a/src/lib/format/parser.go b/src/lib/datafmt/parser.go
index a6e6e5e8e..89fc3cdec 100644
--- a/src/lib/format/parser.go
+++ b/src/lib/datafmt/parser.go
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package format
+package datafmt
import (
"container/vector";
+ "datafmt";
"fmt";
- "format";
"go/scanner";
"go/token";
"io";
diff --git a/src/lib/go/ast/Makefile b/src/lib/go/ast/Makefile
index e21b05d16..5518580c5 100644
--- a/src/lib/go/ast/Makefile
+++ b/src/lib/go/ast/Makefile
@@ -42,14 +42,21 @@ coverage: packages
O1=\
ast.$O\
+O2=\
+ format.$O\
-phases: a1
+
+phases: a1 a2
_obj$D/ast.a: phases
a1: $(O1)
$(AR) grc _obj$D/ast.a ast.$O
rm -f $(O1)
+a2: $(O2)
+ $(AR) grc _obj$D/ast.a format.$O
+ rm -f $(O2)
+
newpkg: clean
mkdir -p _obj$D
@@ -57,6 +64,7 @@ newpkg: clean
$(O1): newpkg
$(O2): a1
+$(O3): a2
nuke: clean
rm -f $(GOROOT)/pkg$D/ast.a
diff --git a/src/lib/go/ast/format.go b/src/lib/go/ast/format.go
new file mode 100644
index 000000000..db7be71ce
--- /dev/null
+++ b/src/lib/go/ast/format.go
@@ -0,0 +1,123 @@
+// 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 ast
+
+import (
+ "datafmt";
+ "go/ast";
+ "go/token";
+ "io";
+ "os";
+)
+
+
+// Format is a customized datafmt.Format for printing of ASTs.
+type Format datafmt.Format;
+
+
+// ----------------------------------------------------------------------------
+// Custom formatters
+
+// The AST-specific formatting state is maintained by a state variable.
+type state struct {
+ // for now we have very little state
+ // TODO maintain list of unassociated comments
+ optSemi *bool
+}
+
+
+func (s *state) Copy() datafmt.Environment {
+ optSemi := *s.optSemi;
+ return &state{&optSemi};
+}
+
+
+func isValidPos(s *datafmt.State, value interface{}, ruleName string) bool {
+ pos := value.(token.Position);
+ return pos.IsValid();
+}
+
+
+func isSend(s *datafmt.State, value interface{}, ruleName string) bool {
+ return value.(ast.ChanDir) & ast.SEND != 0;
+}
+
+
+func isRecv(s *datafmt.State, value interface{}, ruleName string) bool {
+ return value.(ast.ChanDir) & ast.RECV != 0;
+}
+
+
+func isMultiLineComment(s *datafmt.State, value interface{}, ruleName string) bool {
+ return value.([]byte)[1] == '*';
+}
+
+
+func clearOptSemi(s *datafmt.State, value interface{}, ruleName string) bool {
+ *s.Env().(*state).optSemi = false;
+ return true;
+}
+
+
+func setOptSemi(s *datafmt.State, value interface{}, ruleName string) bool {
+ *s.Env().(*state).optSemi = true;
+ return true;
+}
+
+
+func optSemi(s *datafmt.State, value interface{}, ruleName string) bool {
+ if !*s.Env().(*state).optSemi {
+ s.Write([]byte{';'});
+ }
+ return true;
+}
+
+
+var fmap = datafmt.FormatterMap {
+ "isValidPos": isValidPos,
+ "isSend": isSend,
+ "isRecv": isRecv,
+ "isMultiLineComment": isMultiLineComment,
+ "/": clearOptSemi,
+ "clearOptSemi": clearOptSemi,
+ "setOptSemi": setOptSemi,
+ "optSemi": optSemi,
+}
+
+
+// ----------------------------------------------------------------------------
+// Printing
+
+// NewFormat parses a datafmt format specification from a file
+// and adds AST-specific custom formatter rules. The result is
+// the customized format or an os.Error, if any.
+//
+func NewFormat(filename string) (Format, os.Error) {
+ src, err := io.ReadFile(filename);
+ if err != nil {
+ return nil, err;
+ }
+ f, err := datafmt.Parse(src, fmap);
+ return Format(f), err;
+}
+
+
+// Fprint formats each AST node provided as argument according to the
+// format f and writes to standard output. The result is the total number
+// of bytes written and an os.Error, if any.
+//
+func (f Format) Fprint(w io.Writer, nodes ...) (int, os.Error) {
+ s := state{new(bool)};
+ return datafmt.Format(f).Fprint(w, &s, nodes);
+}
+
+
+// Fprint formats each AST node provided as argument according to the
+// format f and writes to w. The result is the total number of bytes
+// written and an os.Error, if any.
+//
+func (f Format) Print(nodes ...) (int, os.Error) {
+ return f.Fprint(os.Stdout, nodes);
+}