diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/Make.deps | 4 | ||||
| -rw-r--r-- | src/lib/Makefile | 4 | ||||
| -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/Makefile | 10 | ||||
| -rw-r--r-- | src/lib/go/ast/format.go | 123 | 
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); +} | 
