Commit 40d54352 authored by Rob Pike's avatar Rob Pike

update tutorial to new language.

add a section on printing
add a section on allocation

R=rsc
DELTA=500  (278 added, 15 deleted, 207 changed)
OCL=22381
CL=22456
parent dfc3e523
This diff is collapsed.
......@@ -20,6 +20,11 @@
#
# non-blank lines are annotated with line number in file
# line numbers are printed %.2d to make them equal-width for nice formatting.
# the format gives a leading 0. the format %2d gives a leading space but
# that appears to confuse sanjay's makehtml formatter into bungling quotes
# because it makes some lines look indented.
echo "<pre> <!-- $* -->"
case $# in
......@@ -27,27 +32,31 @@ case $# in
if test "$3" = "END" # $2 to end of file
then
awk '
function LINE() { printf("%.2d\t%s\n", NR, $0) }
BEGIN { printing = 0 }
'$2' { printing = 1; print NR "\t" $0; getline }
printing { if($0 ~ /./) { print NR "\t" $0 } else { print "" } }
'$2' { printing = 1; LINE(); getline }
printing { if($0 ~ /./) { LINE() } else { print "" } }
'
else # $2 through $3
awk '
function LINE() { printf("%.2d\t%s\n", NR, $0) }
BEGIN { printing = 0 }
'$2' { printing = 1; print NR "\t" $0; getline }
'$3' && printing { if(printing) {printing = 0; print NR "\t" $0; exit} }
printing { if($0 ~ /./) { print NR "\t" $0 } else { print "" } }
'$2' { printing = 1; LINE(); getline }
'$3' && printing { if(printing) {printing = 0; LINE(); exit} }
printing { if($0 ~ /./) { LINE() } else { print "" } }
'
fi
;;
2) # one line
awk '
'$2' { print NR "\t" $0; getline; exit }
function LINE() { printf("%.2d\t%s\n", NR, $0) }
'$2' { LINE(); getline; exit }
'
;;
1) # whole file
awk '
{ if($0 ~ /./) { print NR "\t" $0 } else { print "" } }
function LINE() { printf("%.2d\t%s\n", NR, $0) }
{ if($0 ~ /./) { LINE() } else { print "" } }
'
;;
*)
......
......@@ -5,40 +5,40 @@
package main
import (
FD "fd";
Flag "flag";
"fd";
"flag";
)
func cat(fd *FD.FD) {
func cat(file *fd.FD) {
const NBUF = 512;
var buf [NBUF]byte;
for {
switch nr, er := fd.Read(buf); true {
switch nr, er := file.Read(buf); true {
case nr < 0:
print("error reading from ", fd.Name(), ": ", er, "\n");
print("error reading from ", file.String(), ": ", er.String(), "\n");
sys.exit(1);
case nr == 0: // EOF
return;
case nr > 0:
if nw, ew := FD.Stdout.Write(buf[0:nr]); nw != nr {
print("error writing from ", fd.Name(), ": ", ew, "\n");
if nw, ew := fd.Stdout.Write(buf[0:nr]); nw != nr {
print("error writing from ", file.String(), ": ", ew.String(), "\n");
}
}
}
}
func main() {
Flag.Parse(); // Scans the arg list and sets up flags
if Flag.NArg() == 0 {
cat(FD.Stdin);
flag.Parse(); // Scans the arg list and sets up flags
if flag.NArg() == 0 {
cat(fd.Stdin);
}
for i := 0; i < Flag.NArg(); i++ {
fd, err := FD.Open(Flag.Arg(i), 0, 0);
if fd == nil {
print("can't open ", Flag.Arg(i), ": error ", err, "\n");
for i := 0; i < flag.NArg(); i++ {
file, err := fd.Open(flag.Arg(i), 0, 0);
if file == nil {
print("can't open ", flag.Arg(i), ": error ", err, "\n");
sys.exit(1);
}
cat(fd);
fd.Close();
cat(file);
file.Close();
}
}
......@@ -5,11 +5,12 @@
package main
import (
FD "fd";
Flag "flag";
"fd";
"flag";
"os";
)
var rot13_flag = Flag.Bool("rot13", false, nil, "rot13 the input")
var rot13_flag = flag.Bool("rot13", false, "rot13 the input")
func rot13(b byte) byte {
if 'a' <= b && b <= 'z' {
......@@ -22,8 +23,8 @@ func rot13(b byte) byte {
}
type Reader interface {
Read(b []byte) (ret int64, errno int64);
Name() string;
Read(b []byte) (ret int, err *os.Error);
String() string;
}
type Rot13 struct {
......@@ -31,21 +32,19 @@ type Rot13 struct {
}
func NewRot13(source Reader) *Rot13 {
r13 := new(Rot13);
r13.source = source;
return r13
return &Rot13{source}
}
func (r13 *Rot13) Read(b []byte) (ret int64, errno int64) { // TODO: use standard Read sig?
func (r13 *Rot13) Read(b []byte) (ret int, err *os.Error) {
r, e := r13.source.Read(b);
for i := int64(0); i < r; i++ {
for i := 0; i < r; i++ {
b[i] = rot13(b[i])
}
return r, e
}
func (r13 *Rot13) Name() string {
return r13.source.Name()
func (r13 *Rot13) String() string {
return r13.source.String()
}
// end of Rot13 implementation
......@@ -53,38 +52,37 @@ func cat(r Reader) {
const NBUF = 512;
var buf [NBUF]byte;
if rot13_flag.BVal() {
if *rot13_flag {
r = NewRot13(r)
}
for {
switch nr, er := r.Read(buf); {
case nr < 0:
print("error reading from ", r.Name(), ": ", er, "\n");
print("error reading from ", r.String(), ": ", er.String(), "\n");
sys.exit(1);
case nr == 0: // EOF
return;
case nr > 0:
nw, ew := FD.Stdout.Write(buf[0:nr]);
nw, ew := fd.Stdout.Write(buf[0:nr]);
if nw != nr {
print("error writing from ", r.Name(), ": ", ew, "\n");
print("error writing from ", r.String(), ": ", ew.String(), "\n");
}
}
}
}
func main() {
var bug FD.FD;
Flag.Parse(); // Scans the arg list and sets up flags
if Flag.NArg() == 0 {
cat(FD.Stdin);
flag.Parse(); // Scans the arg list and sets up flags
if flag.NArg() == 0 {
cat(fd.Stdin);
}
for i := 0; i < Flag.NArg(); i++ {
fd, err := FD.Open(Flag.Arg(i), 0, 0);
if fd == nil {
print("can't open ", Flag.Arg(i), ": error ", err, "\n");
for i := 0; i < flag.NArg(); i++ {
file, err := fd.Open(flag.Arg(i), 0, 0);
if file == nil {
print("can't open ", flag.Arg(i), ": error ", err, "\n");
sys.exit(1);
}
cat(fd);
fd.Close();
cat(file);
file.Close();
}
}
......@@ -5,11 +5,11 @@
package main
import (
OS "os";
Flag "flag";
"os";
"flag";
)
var n_flag = Flag.Bool("n", false, nil, "don't print final newline")
var n_flag = flag.Bool("n", false, "don't print final newline")
const (
Space = " ";
......@@ -17,16 +17,16 @@ const (
)
func main() {
Flag.Parse(); // Scans the arg list and sets up flags
flag.Parse(); // Scans the arg list and sets up flags
var s string = "";
for i := 0; i < Flag.NArg(); i++ {
for i := 0; i < flag.NArg(); i++ {
if i > 0 {
s += Space
}
s += Flag.Arg(i)
s += flag.Arg(i)
}
if !n_flag.BVal() {
if !*n_flag {
s += Newline
}
OS.Stdout.WriteString(s);
os.Stdout.WriteString(s);
}
......@@ -4,21 +4,21 @@
package fd
import Syscall "syscall"
import (
"os";
"syscall";
)
export type FD struct {
fildes int64; // file descriptor number
name string; // file name at Open time
fildes int64; // file descriptor number
name string; // file name at Open time
}
func NewFD(fd int64, name string) *FD {
if fd < 0 {
return nil
}
n := new(FD);
n.fildes = fd;
n.name = name;
return n
return &FD{fd, name}
}
export var (
......@@ -27,36 +27,36 @@ export var (
Stderr = NewFD(2, "/dev/stderr");
)
export func Open(name string, mode int64, perm int64) (fd *FD, errno int64) {
r, e := Syscall.open(name, mode, perm);
return NewFD(r, name), e
export func Open(name string, mode int64, perm int64) (fd *FD, err *os.Error) {
r, e := syscall.open(name, mode, perm);
return NewFD(r, name), os.ErrnoToError(e)
}
func (fd *FD) Close() int64 {
func (fd *FD) Close() *os.Error {
if fd == nil {
return Syscall.EINVAL
return os.EINVAL
}
r, e := Syscall.close(fd.fildes);
r, e := syscall.close(fd.fildes);
fd.fildes = -1; // so it can't be closed again
return 0
return nil
}
func (fd *FD) Read(b []byte) (ret int64, errno int64) {
func (fd *FD) Read(b []byte) (ret int, err *os.Error) {
if fd == nil {
return -1, Syscall.EINVAL
return -1, os.EINVAL
}
r, e := Syscall.read(fd.fildes, &b[0], int64(len(b)));
return r, e
r, e := syscall.read(fd.fildes, &b[0], int64(len(b)));
return int(r), os.ErrnoToError(e)
}
func (fd *FD) Write(b []byte) (ret int64, errno int64) {
func (fd *FD) Write(b []byte) (ret int, err *os.Error) {
if fd == nil {
return -1, Syscall.EINVAL
return -1, os.EINVAL
}
r, e := Syscall.write(fd.fildes, &b[0], int64(len(b)));
return r, e
r, e := syscall.write(fd.fildes, &b[0], int64(len(b)));
return int(r), os.ErrnoToError(e)
}
func (fd *FD) Name() string {
func (fd *FD) String() string {
return fd.name
}
......@@ -4,8 +4,8 @@
package main
import OS "os" // this package contains features for basic I/O
import "os" // this package contains features for basic I/O
func main() {
OS.Stdout.WriteString("Hello, world; or Καλημέρα κόσμε; or こんにちは 世界\n");
os.Stdout.WriteString("Hello, world; or Καλημέρα κόσμε; or こんにちは 世界\n");
}
......@@ -4,14 +4,14 @@
package main
import FD "fd"
import fd "fd"
func main() {
hello := []byte{'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '\n'};
FD.Stdout.Write(hello);
fd, errno := FD.Open("/does/not/exist", 0, 0);
if fd == nil {
print("can't open file; errno=", errno, "\n");
fd.Stdout.Write(hello);
file, err := fd.Open("/does/not/exist", 0, 0);
if file == nil {
print("can't open file; err=", err.String(), "\n");
sys.exit(1);
}
}
// 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 main
import "fmt"
func main() {
var u64 uint64 = 1<<64-1;
fmt.printf("%d %d\n", u64, int64(u64));
// harder stuff
type T struct { a int; b string };
t := T{77, "Sunset Strip"};
a := []int{1, 2, 3, 4};
fmt.printf("%v %v %v\n", u64, t, a);
fmt.print(u64, " ", t, " ", a, "\n");
fmt.println(u64, t, a);
}
// 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 main
import "fmt"
type T struct { a int; b string }
func (t *T) String() string {
return fmt.sprint(t.a) + " " + t.b
}
func main() {
t := &T{77, "Sunset Strip"};
fmt.println(t)
}
// 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 main
import "fmt"
func main() {
fmt.printf("hello, %s\n", "world");
}
......@@ -16,6 +16,9 @@ for i in \
sum.go \
sort.go \
sortmain.go \
print.go \
printf.go \
print_string.go \
sieve.go \
sieve1.go \
server1.go \
......@@ -46,7 +49,7 @@ function testitpipe {
testit helloworld "" "Hello, world; or Καλημέρα κόσμε; or こんにちは 世界"
testit helloworld2 "" "Hello, world; or Καλημέρα κόσμε; or こんにちは 世界"
testit helloworld3 "" "hello, world can't open file; errno=2"
testit helloworld3 "" "hello, world can't open file; err=No such file or directory"
testit echo "hello, world" "hello, world"
testit sum "" "6"
......@@ -58,6 +61,10 @@ echo $rot13 | testit cat_rot13 "--rot13" $alphabet
testit sortmain "" "Sunday Monday Tuesday Thursday Friday"
testit print "" "18446744073709551615 -1 18446744073709551615 {77 Sunset Strip} [1 2 3 4] 18446744073709551615 {77 Sunset Strip} [1 2 3 4] 18446744073709551615 {77 Sunset Strip} [1 2 3 4]"
testit printf "" "hello, world"
testit print_string "" "77 Sunset Strip"
testitpipe sieve "sed 10q" "2 3 5 7 11 13 17 19 23 29"
testitpipe sieve "sed 10q" "2 3 5 7 11 13 17 19 23 29"
......
......@@ -5,8 +5,8 @@
package main
type Request struct {
a, b int;
replyc chan int;
a, b int;
replyc chan int;
}
type BinOp (a, b int) int;
......
......@@ -5,26 +5,23 @@
package sort
export type SortInterface interface {
len() int;
less(i, j int) bool;
swap(i, j int);
Len() int;
Less(i, j int) bool;
Swap(i, j int);
}
export func Sort(data SortInterface) {
// Bubble sort for brevity
for i := 0; i < data.len(); i++ {
for j := i; j < data.len(); j++ {
if data.less(j, i) {
data.swap(i, j)
}
for i := 1; i < data.Len(); i++ {
for j := i; j > 0 && data.Less(j, j-1); j-- {
data.Swap(j, j-1);
}
}
}
export func IsSorted(data SortInterface) bool {
n := data.len();
n := data.Len();
for i := n - 1; i > 0; i-- {
if data.less(i, i - 1) {
if data.Less(i, i - 1) {
return false;
}
}
......@@ -33,40 +30,34 @@ export func IsSorted(data SortInterface) bool {
// Convenience types for common cases
export type IntArray struct {
data *[]int;
}
export type IntArray []int
func (p *IntArray) len() int { return len(p.data); }
func (p *IntArray) less(i, j int) bool { return p.data[i] < p.data[j]; }
func (p *IntArray) swap(i, j int) { p.data[i], p.data[j] = p.data[j], p.data[i]; }
func (p IntArray) Len() int { return len(p); }
func (p IntArray) Less(i, j int) bool { return p[i] < p[j]; }
func (p IntArray) Swap(i, j int) { p[i], p[j] = p[j], p[i]; }
export type FloatArray struct {
data *[]float;
}
export type FloatArray []float
func (p *FloatArray) len() int { return len(p.data); }
func (p *FloatArray) less(i, j int) bool { return p.data[i] < p.data[j]; }
func (p *FloatArray) swap(i, j int) { p.data[i], p.data[j] = p.data[j], p.data[i]; }
func (p FloatArray) Len() int { return len(p); }
func (p FloatArray) Less(i, j int) bool { return p[i] < p[j]; }
func (p FloatArray) Swap(i, j int) { p[i], p[j] = p[j], p[i]; }
export type StringArray struct {
data *[]string;
}
export type StringArray []string
func (p *StringArray) len() int { return len(p.data); }
func (p *StringArray) less(i, j int) bool { return p.data[i] < p.data[j]; }
func (p *StringArray) swap(i, j int) { p.data[i], p.data[j] = p.data[j], p.data[i]; }
func (p StringArray) Len() int { return len(p); }
func (p StringArray) Less(i, j int) bool { return p[i] < p[j]; }
func (p StringArray) Swap(i, j int) { p[i], p[j] = p[j], p[i]; }
// Convenience wrappers for common cases
export func SortInts(a *[]int) { Sort(&IntArray{a}); }
export func SortFloats(a *[]float) { Sort(&FloatArray{a}); }
export func SortStrings(a *[]string) { Sort(&StringArray{a}); }
export func SortInts(a []int) { Sort(IntArray(a)); }
export func SortFloats(a []float) { Sort(FloatArray(a)); }
export func SortStrings(a []string) { Sort(StringArray(a)); }
export func IntsAreSorted(a *[]int) bool { return IsSorted(&IntArray{a}); }
export func FloatsAreSorted(a *[]float) bool { return IsSorted(&FloatArray{a}); }
export func StringsAreSorted(a *[]string) bool { return IsSorted(&StringArray{a}); }
export func IntsAreSorted(a []int) bool { return IsSorted(IntArray(a)); }
export func FloatsAreSorted(a []float) bool { return IsSorted(FloatArray(a)); }
export func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)); }
......@@ -4,22 +4,22 @@
package main
import Sort "sort"
import "sort"
func ints() {
data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586};
a := Sort.IntArray{&data};
Sort.Sort(&a);
if !Sort.IsSorted(&a) {
a := sort.IntArray(data);
sort.Sort(a);
if !sort.IsSorted(a) {
panic()
}
}
func strings() {
data := []string{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"};
a := Sort.StringArray{&data};
Sort.Sort(&a);
if !Sort.IsSorted(&a) {
a := sort.StringArray(data);
sort.Sort(a);
if !sort.IsSorted(a) {
panic()
}
}
......@@ -31,12 +31,12 @@ type Day struct {
}
type DayArray struct {
data *[]*Day;
data []*Day;
}
func (p *DayArray) len() int { return len(p.data); }
func (p *DayArray) less(i, j int) bool { return p.data[i].num < p.data[j].num; }
func (p *DayArray) swap(i, j int) { p.data[i], p.data[j] = p.data[j], p.data[i]; }
func (p *DayArray) Len() int { return len(p.data); }
func (p *DayArray) Less(i, j int) bool { return p.data[i].num < p.data[j].num; }
func (p *DayArray) Swap(i, j int) { p.data[i], p.data[j] = p.data[j], p.data[i]; }
func days() {
Sunday := Day{ 0, "SUN", "Sunday" };
......@@ -47,13 +47,13 @@ func days() {
Friday := Day{ 5, "FRI", "Friday" };
Saturday := Day{ 6, "SAT", "Saturday" };
data := []*Day{&Tuesday, &Thursday, &Sunday, &Monday, &Friday};
a := DayArray{&data};
Sort.Sort(&a);
if !Sort.IsSorted(&a) {
a := DayArray{data};
sort.Sort(&a);
if !sort.IsSorted(&a) {
panic()
}
for i := 0; i < len(data); i++ {
print(data[i].long_name, " ")
for i, d := range data {
print(d.long_name, " ")
}
print("\n")
}
......
......@@ -4,7 +4,7 @@
package main
func sum(a *[]int) int { // returns an int
func sum(a []int) int { // returns an int
s := 0;
for i := 0; i < len(a); i++ {
s += a[i]
......@@ -14,6 +14,6 @@ func sum(a *[]int) int { // returns an int
func main() {
s := sum(&[]int{1,2,3}); // pass address of int array
s := sum([3]int{1,2,3}); // a slice of the array is passed to sum
print(s, "\n");
}
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