pl0

package module
v1.0.1-0...-3288856 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 9, 2018 License: BSD-3-Clause Imports: 12 Imported by: 0

README

pl0

PL/0 front end, compiler and VM.

Installation

$ go get modernc.org/pl0/...

Documentation: godoc.org/modernc.org/pl0

PL/0 executor documentation: godoc.org/modernc.org/pl0/pl0

Documentation

Overview

Package pl0 is a PL/0[0] compiler front end.

For an example using the front end see the pl0 command in the pl0 subdirectory.

Purpose

This is a showcase demonstrating use of:

fe	http://godoc.org/modernc.org/fe
golex	http://godoc.org/modernc.org/golex
goyacc	http://godoc.org/modernc.org/goyacc
lex	http://godoc.org/modernc.org/golex/lex
xc	http://godoc.org/modernc.org/xc
yy	http://godoc.org/modernc.org/yy
Example (IllegalAssignment)
_, err := ParseString("",
	`
	CONST a = 42;
	
	VAR b;
	
	PROCEDURE c;
	BEGIN
	END;
	
	BEGIN
		a := 1;
		b := 1;
		c := 1;
	END.
`)

scanner.PrintError(os.Stdout, err)
Output:

11:3: a is not a variable
13:3: c is not a variable
Example (IllegalCall)
_, err := ParseString("",
	`
	CONST a = 42;
	
	VAR b;
	
	PROCEDURE c;
	BEGIN
	END;
	
	BEGIN
		CALL a;
		CALL b;
		CALL c;
	END.
`)

scanner.PrintError(os.Stdout, err)
Output:

11:8: a is not a procedure
12:8: b is not a procedure
Example (IllegalFactor)
_, err := ParseString("",
	`
	CONST a = 42;
	
	VAR b;
	
	PROCEDURE c;
	BEGIN
	END;
	
	BEGIN
		b := a;
		b := b;
		b := c;
	END.
`)

scanner.PrintError(os.Stdout, err)
Output:

13:8: c is not a constant or a variable
Example (IllegalRead)
_, err := ParseString("",
	`
	CONST a = 42;
	
	VAR b;
	
	PROCEDURE c;
	BEGIN
	END;
	
	BEGIN
		? a;
		? b;
		? c;
	END.
`)

scanner.PrintError(os.Stdout, err)
Output:

11:5: a is not a variable
13:5: c is not a variable
Example (List)
prog, err := ParseString("",
	`
	VAR v;
	
	PROCEDURE addOne;
	BEGIN
		v := v + 1;
	END;

	BEGIN // main
		v := 42;
		CALL addOne;
		! v;
	END.
`)

if err != nil {
	panic(err)
}

prog.List(os.Stdout)
Output:

00000000:	call		00000002	// -
00000001:	halt

00000002:	enter		1, 0		// 2:2:
00000003:	jmp		00000011

00000004:	enter		0, 1		// 4:12: addOne
00000005:	jmp		00000006

00000006:	pushVar		1, 0		// 2:6: v
00000007:	pushConst	1		// 6:12
00000008:	add				// 6:10
00000009:	popVar		1, 0		// 2:6: v
00000010:	leave

00000011:	pushConst	42		// 10:8
00000012:	popVar		0		// 2:6: v
00000013:	call		00000004	// 11:3
00000014:	pushVar		0		// 2:6: v
00000015:	write				// 12:3
00000016:	leave
Example (Program1)
prog, err := ParseString("",
	`
	// Original source: https://en.wikipedia.org/wiki/PL/0#Examples
	
	VAR x, squ;
	
	PROCEDURE square;
	BEGIN
		squ := x * x
	END;
	
	BEGIN
		x := 1;
		WHILE x <= 10 DO
		BEGIN
			CALL square;
			! squ;
			x := x + 1
		END
	END.
`)

if err != nil {
	panic(err)
}

if err := prog.Run(); err != nil {
	panic(err)
}
Output:

1
4
9
16
25
36
49
64
81
100
Example (Program2)
prog, err := ParseString("",
	`
	// Original source: https://en.wikipedia.org/wiki/PL/0#Examples
	
	CONST
		m =  7,
		n = 85;
	
	VAR
	 	x, y, z, q, r;
	
	PROCEDURE multiply;
	VAR a, b;
	
	BEGIN
		a := x;
		b := y;
		z := 0;
		WHILE b > 0 DO BEGIN
			IF ODD b THEN z := z + a;
			a := 2 * a;
			b := b / 2
		END;
		! z
	END;
	
	PROCEDURE divide;
	VAR w;
	BEGIN
		r := x;
		q := 0;
		w := y;
		WHILE w <= r DO w := 2 * w;
		WHILE w > y DO BEGIN
			q := 2 * q;
			w := w / 2;
			IF w <= r THEN BEGIN
				r := r - w;
				q := q + 1
			END
		END;
		! q;
		! r
	END;
	
	PROCEDURE gcd;
	VAR f, g;
	BEGIN
		f := x;
		g := y;
		WHILE f # g DO BEGIN
			IF f < g THEN g := g - f;
			IF g < f THEN f := f - g
		END;
		z := f;
		! z;
	END;
	
	BEGIN
		x := m;
		y := n;
		CALL multiply;
		x := 25;
		y :=  3;
		CALL divide;
		x := 84;
		y := 36;
		CALL gcd
	END.
`)

if err != nil {
	panic(err)
}

if err := prog.Run(); err != nil {
	panic(err)
}
Output:

595
8
1
12
Example (Redeclaration)
_, err := ParseString("",
	`
	CONST a = 42, b = 24, a = 314;
	
	VAR b, c, d;
	
	PROCEDURE c;
	BEGIN
	END;
	
	PROCEDURE d;
	BEGIN
	END;
	
	PROCEDURE e;
	BEGIN
	END;
	
	PROCEDURE e;
	BEGIN
	END;
	
	BEGIN
	END.
`)

scanner.PrintError(os.Stdout, err)
Output:

2:24: redeclaration of a at 2:8
4:6: redeclaration of b at 2:16
6:12: redeclaration of c at 4:9
10:12: redeclaration of d at 4:12
18:12: redeclaration of e at 14:12
Example (StackFrames)
prog, err := ParseString("",
	`
	VAR a1, recur;
	
	PROCEDURE p2;
	VAR a2;

		PROCEDURE p3;
		VAR a3;
		BEGIN // p3
			a3 := 3;
			! 333333;
			! a1;
			! a2;
			! a3;
		END;

		PROCEDURE p4;
		VAR a3;
		BEGIN // p4
			a3 := 4;
			CALL p3;
			! 444444;
			! a1;
			! a2;
			! a3;
			WHILE recur > 0 DO BEGIN
				recur := recur - 1;
				CALL p2;
			END;
		END;

	BEGIN // p2
		a2 := 2;
		! 222222;
		! a1;
		! a2;
		CALL p4;
	END;
	
	BEGIN // main
		a1 := 1;
		recur := 2;
		! 111111;
		! a1;
		CALL p2;
		! 999999;
	END.
`)

if err != nil {
	panic(err)
}

if err := prog.Run(); err != nil {
	panic(err)
}
Output:

111111
1
222222
1
2
333333
1
2
3
444444
1
2
4
222222
1
2
333333
1
2
3
444444
1
2
4
222222
1
2
333333
1
2
3
444444
1
2
4
999999
Example (StackTrace)
prog, err := ParseString("",
	`
	VAR v;
	
	PROCEDURE addOne;
	BEGIN
		v := v + 1;
	END;

	BEGIN // main
		v := 42;
		CALL addOne;
		! v;
	END.
`)

if err != nil {
	panic(err)
}

if err := prog.Run(TraceStack()); err != nil {
	panic(err)
}
Output:

T 0001,  FP 0000, SP 0000, []:	00000000:	call		00000002	// -
T 0002,  FP 0000, SP 0001, [1]:	00000002:	enter		1, 0		// 2:2:
T 0003,  FP 0003, SP 0004, [1 0 0 0]:	00000003:	jmp		00000011
T 0004,  FP 0003, SP 0004, [1 0 0 0]:	00000011:	pushConst	42		// 10:8
T 0005,  FP 0003, SP 0005, [1 0 0 0 42]:	00000012:	popVar		0		// 2:6: v
T 0006,  FP 0003, SP 0004, [1 0 0 42]:	00000013:	call		00000004	// 11:3
T 0007,  FP 0003, SP 0005, [1 0 0 42 14]:	00000004:	enter		0, 1		// 4:12: addOne
T 0008,  FP 0008, SP 0008, [1 0 0 42 14 3 3 1]:	00000005:	jmp		00000006
T 0009,  FP 0008, SP 0008, [1 0 0 42 14 3 3 1]:	00000006:	pushVar		1, 0		// 2:6: v
T 0010,  FP 0008, SP 0009, [1 0 0 42 14 3 3 1 42]:	00000007:	pushConst	1		// 6:12
T 0011,  FP 0008, SP 0010, [1 0 0 42 14 3 3 1 42 1]:	00000008:	add				// 6:10
T 0012,  FP 0008, SP 0009, [1 0 0 42 14 3 3 1 43]:	00000009:	popVar		1, 0		// 2:6: v
T 0013,  FP 0008, SP 0008, [1 0 0 43 14 3 3 1]:	00000010:	leave
T 0014,  FP 0003, SP 0004, [1 0 0 43]:	00000014:	pushVar		0		// 2:6: v
T 0015,  FP 0003, SP 0005, [1 0 0 43 43]:	00000015:	write				// 12:3
43
T 0016,  FP 0003, SP 0004, [1 0 0 43]:	00000016:	leave
T 0017,  FP 0000, SP 0000, []:	00000001:	halt
Example (Trace)
prog, err := ParseString("",
	`
	VAR v;
	
	PROCEDURE addOne;
	BEGIN
		v := v + 1;
	END;

	BEGIN // main
		v := 42;
		CALL addOne;
		! v;
	END.
`)

if err != nil {
	panic(err)
}

if err := prog.Run(Trace()); err != nil {
	panic(err)
}
Output:

T 0001,  FP 0000, SP 0000:	00000000:	call		00000002	// -
T 0002,  FP 0000, SP 0001:	00000002:	enter		1, 0		// 2:2:
T 0003,  FP 0003, SP 0004:	00000003:	jmp		00000011
T 0004,  FP 0003, SP 0004:	00000011:	pushConst	42		// 10:8
T 0005,  FP 0003, SP 0005:	00000012:	popVar		0		// 2:6: v
T 0006,  FP 0003, SP 0004:	00000013:	call		00000004	// 11:3
T 0007,  FP 0003, SP 0005:	00000004:	enter		0, 1		// 4:12: addOne
T 0008,  FP 0008, SP 0008:	00000005:	jmp		00000006
T 0009,  FP 0008, SP 0008:	00000006:	pushVar		1, 0		// 2:6: v
T 0010,  FP 0008, SP 0009:	00000007:	pushConst	1		// 6:12
T 0011,  FP 0008, SP 0010:	00000008:	add				// 6:10
T 0012,  FP 0008, SP 0009:	00000009:	popVar		1, 0		// 2:6: v
T 0013,  FP 0008, SP 0008:	00000010:	leave
T 0014,  FP 0003, SP 0004:	00000014:	pushVar		0		// 2:6: v
T 0015,  FP 0003, SP 0005:	00000015:	write				// 12:3
43
T 0016,  FP 0003, SP 0004:	00000016:	leave
T 0017,  FP 0000, SP 0000:	00000001:	halt
Example (Undeclared)
_, err := ParseString("",
	`
	CONST a = 42;
	
	VAR b;
	
	PROCEDURE c;
	BEGIN
		CALL aa;
		CALL c;
	END;
	
	BEGIN
		b := a;
		b := d;
		e := 10;
		CALL c;
		CALL f;
		? b;
		? g;
	END.
`)

scanner.PrintError(os.Stdout, err)
Output:

8:8: undeclared identifier aa
14:8: undeclared identifier d
15:3: undeclared identifier e
17:8: undeclared identifier f
19:5: undeclared identifier g

Index

Examples

Constants

View Source
const (
	ASSIGN    = 57346
	BEGIN     = 57347
	CALL      = 57348
	CONST     = 57349
	DO        = 57350
	END       = 57351
	GEQ       = 57352
	IDENT     = 57353
	IF        = 57354
	LEQ       = 57355
	NUMBER    = 57356
	ODD       = 57357
	PROCEDURE = 57358
	THEN      = 57359
	VAR       = 57360
	WHILE     = 57361
)

Variables

This section is empty.

Functions

func PrettyString

func PrettyString(v interface{}) string

PrettyString returns a pretty formatted representation of AST nodes.

Types

type Add

type Add struct {
	Addr
	Token xc.Token
}

Add is an Instruction adding the top two stack items.

func (*Add) Execute

func (n *Add) Execute(m *VM)

Execute implements Instruction.

func (*Add) String

func (n *Add) String() string

String implements fmt.Stringer.

type Addr

type Addr int

Addr represents and address of the VM.

type Binding

type Binding struct {
	Node Node
	Pos  token.Pos
}

Binding is the value bound to a name at Pos.

type Bindings

type Bindings struct {
	Map    map[int]*Binding
	Parent *Bindings
	// contains filtered or unexported fields
}

Bindings capture name -> Binding projections in a scope.

func (*Bindings) Bind

func (b *Bindings) Bind(t xc.Token, node Node, report *xc.Report)

Bind attempts to bind the name in t to node. Errors are reported to report.

type Block

type Block struct {
	ConstsOpt   *ConstsOpt
	ProcListOpt *ProcListOpt
	Statement   *Statement
	VarsOpt     *VarsOpt
	// contains filtered or unexported fields
}

Block represents data reduced by production:

Block:
        ConstsOpt VarsOpt ProcListOpt Statement
Example
fmt.Println(exampleAST(3, "CALL x."))
Output:

&pl0.Block{
· Statement: &pl0.Statement{
· · Case: 2,
· · Token: example3.pl0:1:1: CALL,
· · Token2: example3.pl0:1:6: IDENT "x",
· },
}

func (*Block) Pos

func (n *Block) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*Block) String

func (n *Block) String() string

String implements fmt.Stringer.

type Call

type Call struct {
	Addr
	Target int
	Token  xc.Token
}

Call is an Instruction for calling subroutines.

func (*Call) Execute

func (n *Call) Execute(m *VM)

Execute implements Instruction.

func (*Call) String

func (n *Call) String() string

String implements fmt.Stringer.

type Condition

type Condition struct {
	Case        int
	Expression  *Expression
	Expression2 *Expression
	Token       xc.Token
}

Condition represents data reduced by productions:

Condition:
        "ODD" Expression
|       Expression '=' Expression   // Case 1
|       Expression '#' Expression   // Case 2
|       Expression '<' Expression   // Case 3
|       Expression "<=" Expression  // Case 4
|       Expression '>' Expression   // Case 5
|       Expression ">=" Expression  // Case 6
Example
fmt.Println(exampleAST(36, "IF ODD a DO"))
Output:

&pl0.Condition{
· Expression: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example36.pl0:1:8: IDENT "a",
· · · },
· · },
· },
· Token: example36.pl0:1:4: ODD,
}
Example (Case1)
fmt.Println(exampleAST(37, "IF a = b DO"))
Output:

&pl0.Condition{
· Case: 1,
· Expression: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example37.pl0:1:4: IDENT "a",
· · · },
· · },
· },
· Expression2: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example37.pl0:1:8: IDENT "b",
· · · },
· · },
· },
· Token: example37.pl0:1:6: '=',
}
Example (Case2)
fmt.Println(exampleAST(38, "IF a # b DO"))
Output:

&pl0.Condition{
· Case: 2,
· Expression: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example38.pl0:1:4: IDENT "a",
· · · },
· · },
· },
· Expression2: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example38.pl0:1:8: IDENT "b",
· · · },
· · },
· },
· Token: example38.pl0:1:6: '#',
}
Example (Case3)
fmt.Println(exampleAST(39, "IF a < b DO"))
Output:

&pl0.Condition{
· Case: 3,
· Expression: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example39.pl0:1:4: IDENT "a",
· · · },
· · },
· },
· Expression2: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example39.pl0:1:8: IDENT "b",
· · · },
· · },
· },
· Token: example39.pl0:1:6: '<',
}
Example (Case4)
fmt.Println(exampleAST(40, "IF a <= b DO"))
Output:

&pl0.Condition{
· Case: 4,
· Expression: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example40.pl0:1:4: IDENT "a",
· · · },
· · },
· },
· Expression2: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example40.pl0:1:9: IDENT "b",
· · · },
· · },
· },
· Token: example40.pl0:1:6: LEQ,
}
Example (Case5)
fmt.Println(exampleAST(41, "IF a > b DO"))
Output:

&pl0.Condition{
· Case: 5,
· Expression: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example41.pl0:1:4: IDENT "a",
· · · },
· · },
· },
· Expression2: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example41.pl0:1:8: IDENT "b",
· · · },
· · },
· },
· Token: example41.pl0:1:6: '>',
}
Example (Case6)
fmt.Println(exampleAST(42, "IF a >= b DO"))
Output:

&pl0.Condition{
· Case: 6,
· Expression: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example42.pl0:1:4: IDENT "a",
· · · },
· · },
· },
· Expression2: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example42.pl0:1:9: IDENT "b",
· · · },
· · },
· },
· Token: example42.pl0:1:6: GEQ,
}

func (*Condition) Pos

func (n *Condition) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*Condition) String

func (n *Condition) String() string

String implements fmt.Stringer.

type ConstSpec

type ConstSpec struct {
	Number *Number
	Token  xc.Token
	Token2 xc.Token
}

ConstSpec represents data reduced by production:

ConstSpec:
        IDENT '=' Number
Example
fmt.Println(exampleAST(9, "CONST a = 98 ,"))
Output:

&pl0.ConstSpec{
· Number: &pl0.Number{
· · Value: 98,
· · Token: example9.pl0:1:11: NUMBER "98",
· },
· Token: example9.pl0:1:7: IDENT "a",
· Token2: example9.pl0:1:9: '=',
}

func (*ConstSpec) Pos

func (n *ConstSpec) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*ConstSpec) String

func (n *ConstSpec) String() string

String implements fmt.Stringer.

type ConstSpecList

type ConstSpecList struct {
	Case          int
	ConstSpec     *ConstSpec
	ConstSpecList *ConstSpecList
	Token         xc.Token
}

ConstSpecList represents data reduced by productions:

ConstSpecList:
        ConstSpec
|       ConstSpecList ',' ConstSpec  // Case 1
Example
fmt.Println(exampleAST(7, "CONST a = 98 ,"))
Output:

&pl0.ConstSpecList{
· ConstSpec: &pl0.ConstSpec{
· · Number: &pl0.Number{
· · · Value: 98,
· · · Token: example7.pl0:1:11: NUMBER "98",
· · },
· · Token: example7.pl0:1:7: IDENT "a",
· · Token2: example7.pl0:1:9: '=',
· },
}
Example (Case1)
fmt.Println(exampleAST(8, "CONST a = 98 , c = 100 ,"))
Output:

&pl0.ConstSpecList{
· ConstSpec: &pl0.ConstSpec{
· · Number: &pl0.Number{
· · · Value: 98,
· · · Token: example8.pl0:1:11: NUMBER "98",
· · },
· · Token: example8.pl0:1:7: IDENT "a",
· · Token2: example8.pl0:1:9: '=',
· },
· ConstSpecList: &pl0.ConstSpecList{
· · Case: 1,
· · ConstSpec: &pl0.ConstSpec{
· · · Number: &pl0.Number{
· · · · Value: 100,
· · · · Token: example8.pl0:1:20: NUMBER "100",
· · · },
· · · Token: example8.pl0:1:16: IDENT "c",
· · · Token2: example8.pl0:1:18: '=',
· · },
· · Token: example8.pl0:1:14: ',',
· },
}

func (*ConstSpecList) Pos

func (n *ConstSpecList) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*ConstSpecList) String

func (n *ConstSpecList) String() string

String implements fmt.Stringer.

type Consts

type Consts struct {
	ConstSpecList *ConstSpecList
	Token         xc.Token
	Token2        xc.Token
}

Consts represents data reduced by production:

Consts:
        "CONST" ConstSpecList ';'
Example
fmt.Println(exampleAST(6, "CONST a = 98 ; !"))
Output:

&pl0.Consts{
· ConstSpecList: &pl0.ConstSpecList{
· · ConstSpec: &pl0.ConstSpec{
· · · Number: &pl0.Number{
· · · · Value: 98,
· · · · Token: example6.pl0:1:11: NUMBER "98",
· · · },
· · · Token: example6.pl0:1:7: IDENT "a",
· · · Token2: example6.pl0:1:9: '=',
· · },
· },
· Token: example6.pl0:1:1: CONST,
· Token2: example6.pl0:1:14: ';',
}

func (*Consts) Pos

func (n *Consts) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*Consts) String

func (n *Consts) String() string

String implements fmt.Stringer.

type ConstsOpt

type ConstsOpt struct {
	Consts *Consts
}

ConstsOpt represents data reduced by productions:

ConstsOpt:
        /* empty */
|       Consts       // Case 1
Example
fmt.Println(exampleAST(4, "!") == (*ConstsOpt)(nil))
Output:

true
Example (Case1)
fmt.Println(exampleAST(5, "CONST a = 98 ; !"))
Output:

&pl0.ConstsOpt{
· Consts: &pl0.Consts{
· · ConstSpecList: &pl0.ConstSpecList{
· · · ConstSpec: &pl0.ConstSpec{
· · · · Number: &pl0.Number{
· · · · · Value: 98,
· · · · · Token: example5.pl0:1:11: NUMBER "98",
· · · · },
· · · · Token: example5.pl0:1:7: IDENT "a",
· · · · Token2: example5.pl0:1:9: '=',
· · · },
· · },
· · Token: example5.pl0:1:1: CONST,
· · Token2: example5.pl0:1:14: ';',
· },
}

func (*ConstsOpt) Pos

func (n *ConstsOpt) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*ConstsOpt) String

func (n *ConstsOpt) String() string

String implements fmt.Stringer.

type Div

type Div struct {
	Addr
	Token xc.Token
}

Div is an Instruction dividing the top two stack items.

func (*Div) Execute

func (n *Div) Execute(m *VM)

Execute implements Instruction.

func (*Div) String

func (n *Div) String() string

String implements fmt.Stringer.

type Enter

type Enter struct {
	Addr
	LNL   int // Lexical nesting level.
	NVars int
	Token xc.Token
}

Enter is an Instruction setting up VM.FP and the stack frame upon entry to a subroutine.

func (*Enter) Execute

func (n *Enter) Execute(m *VM)

Execute implements Instruction.

Stack frame before Execute:

      +----------------+
      | Return address |
      +----------------+
SP -> |                |

Stack frame after Execute:

      +----------------+
      | Return address |
      +----------------+
      | Previous FP    |
      +----------------+
      | [LNL]int       | Parent Frame Pointers
      +----------------+
      | LNL            | Lexical Nesting Level
      +----------------+
FP -> | [NVars]int     | Local variables
      +----------------+
SP -> |                ! Evaluation stack

func (*Enter) String

func (n *Enter) String() string

String implements fmt.Stringer.

type Expression

type Expression struct {
	Case       int
	Expression *Expression
	Term       *Term
	Token      xc.Token
}

Expression represents data reduced by productions:

Expression:
        '+' Term
|       '-' Term             // Case 1
|       Term                 // Case 2
|       Expression '+' Term  // Case 3
|       Expression '-' Term  // Case 4
Example
fmt.Println(exampleAST(43, "IF + a #"))
Output:

&pl0.Expression{
· Term: &pl0.Term{
· · Factor: &pl0.Factor{
· · · Token: example43.pl0:1:6: IDENT "a",
· · },
· },
· Token: example43.pl0:1:4: '+',
}
Example (Case1)
fmt.Println(exampleAST(44, "IF - a #"))
Output:

&pl0.Expression{
· Case: 1,
· Term: &pl0.Term{
· · Factor: &pl0.Factor{
· · · Token: example44.pl0:1:6: IDENT "a",
· · },
· },
· Token: example44.pl0:1:4: '-',
}
Example (Case2)
fmt.Println(exampleAST(45, "IF a #"))
Output:

&pl0.Expression{
· Case: 2,
· Term: &pl0.Term{
· · Factor: &pl0.Factor{
· · · Token: example45.pl0:1:4: IDENT "a",
· · },
· },
}
Example (Case3)
fmt.Println(exampleAST(46, "IF a + b #"))
Output:

&pl0.Expression{
· Case: 3,
· Expression: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example46.pl0:1:4: IDENT "a",
· · · },
· · },
· },
· Term: &pl0.Term{
· · Factor: &pl0.Factor{
· · · Token: example46.pl0:1:8: IDENT "b",
· · },
· },
· Token: example46.pl0:1:6: '+',
}
Example (Case4)
fmt.Println(exampleAST(47, "IF a - b #"))
Output:

&pl0.Expression{
· Case: 4,
· Expression: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example47.pl0:1:4: IDENT "a",
· · · },
· · },
· },
· Term: &pl0.Term{
· · Factor: &pl0.Factor{
· · · Token: example47.pl0:1:8: IDENT "b",
· · },
· },
· Token: example47.pl0:1:6: '-',
}

func (*Expression) Pos

func (n *Expression) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*Expression) String

func (n *Expression) String() string

String implements fmt.Stringer.

type Factor

type Factor struct {
	Case       int
	Expression *Expression
	Number     *Number
	Token      xc.Token
	Token2     xc.Token
}

Factor represents data reduced by productions:

Factor:
        IDENT
|       Number              // Case 1
|       '(' Expression ')'  // Case 2
Example
fmt.Println(exampleAST(51, "IF a #"))
Output:

&pl0.Factor{
· Token: example51.pl0:1:4: IDENT "a",
}
Example (Case1)
fmt.Println(exampleAST(52, "WHILE 97 #"))
Output:

&pl0.Factor{
· Case: 1,
· Number: &pl0.Number{
· · Value: 97,
· · Token: example52.pl0:1:7: NUMBER "97",
· },
}
Example (Case2)
fmt.Println(exampleAST(53, "WHILE ( a ) #"))
Output:

&pl0.Factor{
· Case: 2,
· Expression: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example53.pl0:1:9: IDENT "a",
· · · },
· · },
· },
· Token: example53.pl0:1:7: '(',
· Token2: example53.pl0:1:11: ')',
}

func (*Factor) Pos

func (n *Factor) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*Factor) String

func (n *Factor) String() string

String implements fmt.Stringer.

type Halt

type Halt struct {
	Addr
}

Halt is an intruction stopping the VM.

func (*Halt) Execute

func (n *Halt) Execute(m *VM)

Execute implements Instruction.

func (*Halt) String

func (n *Halt) String() string

String implements fmt.Stringer.

type Instruction

type Instruction interface {
	fmt.Stringer

	Execute(*VM)
	// contains filtered or unexported methods
}

Instruction must be implemented by all instructions of VM.

type Jmp

type Jmp struct {
	Addr
	Target int
}

Jmp is an Instruction uncoditionally changing VM.IP.

func (*Jmp) Execute

func (n *Jmp) Execute(m *VM)

Execute implements Instruction.

func (*Jmp) String

func (n *Jmp) String() string

String implements fmt.Stringer.

type JmpZero

type JmpZero struct {
	Addr
	Target int
}

JmpZero is an Instruction coditionally changing VM.IP when TOS == 0.

func (*JmpZero) Execute

func (n *JmpZero) Execute(m *VM)

Execute implements Instruction.

func (*JmpZero) String

func (n *JmpZero) String() string

String implements fmt.Stringer.

type Leave

type Leave struct {
	Addr
}

Leave is an Instruction restoring the stack frame and IP prior to a subroutine call.

func (*Leave) Execute

func (n *Leave) Execute(m *VM)

Execute implements Instruction.

func (*Leave) String

func (n *Leave) String() string

String implements fmt.Stringer.

type Mul

type Mul struct {
	Addr
	Token xc.Token
}

Mul is an Instruction multiplying the top two stack items.

func (*Mul) Execute

func (n *Mul) Execute(m *VM)

Execute implements Instruction.

func (*Mul) String

func (n *Mul) String() string

String implements fmt.Stringer.

type Neg

type Neg struct {
	Addr
	Token xc.Token
}

Neg is an Instruction multiplying TOS by -1.

func (*Neg) Execute

func (n *Neg) Execute(m *VM)

Execute implements Instruction.

func (*Neg) String

func (n *Neg) String() string

String implements fmt.Stringer.

type Node

type Node interface {
	Pos() token.Pos
}

Node must be implemented by all AST nodes.

type Number

type Number struct {
	Value int // Numeric value of the token.
	Token xc.Token
}

Number represents data reduced by production:

Number:
        NUMBER
Example
fmt.Println(exampleAST(10, "WHILE 97 #"))
Output:

&pl0.Number{
· Value: 97,
· Token: example10.pl0:1:7: NUMBER "97",
}

func (*Number) Pos

func (n *Number) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*Number) String

func (n *Number) String() string

String implements fmt.Stringer.

type PopVar

type PopVar struct {
	Addr
	Index  int
	Frames int
	Token  xc.Token
}

PopVar is an Instruction popping a variable on stack.

func (*PopVar) Execute

func (n *PopVar) Execute(m *VM)

Execute implements Instruction.

func (*PopVar) String

func (n *PopVar) String() string

String implements fmt.Stringer.

type ProcList

type ProcList struct {
	Case     int
	ProcList *ProcList
	ProcSpec *ProcSpec
}

ProcList represents data reduced by productions:

ProcList:
        ProcSpec
|       ProcList ProcSpec  // Case 1
Example
fmt.Println(exampleAST(19, "PROCEDURE a ; ; !"))
Output:

&pl0.ProcList{
· ProcSpec: &pl0.ProcSpec{
· · Block: &pl0.Block{
· · },
· · Token: example19.pl0:1:1: PROCEDURE,
· · Token2: example19.pl0:1:11: IDENT "a",
· · Token3: example19.pl0:1:13: ';',
· · Token4: example19.pl0:1:15: ';',
· },
}
Example (Case1)
fmt.Println(exampleAST(20, "PROCEDURE a ; ; PROCEDURE b ; ; !"))
Output:

&pl0.ProcList{
· ProcList: &pl0.ProcList{
· · Case: 1,
· · ProcSpec: &pl0.ProcSpec{
· · · Block: &pl0.Block{
· · · },
· · · Token: example20.pl0:1:17: PROCEDURE,
· · · Token2: example20.pl0:1:27: IDENT "b",
· · · Token3: example20.pl0:1:29: ';',
· · · Token4: example20.pl0:1:31: ';',
· · },
· },
· ProcSpec: &pl0.ProcSpec{
· · Block: &pl0.Block{
· · },
· · Token: example20.pl0:1:1: PROCEDURE,
· · Token2: example20.pl0:1:11: IDENT "a",
· · Token3: example20.pl0:1:13: ';',
· · Token4: example20.pl0:1:15: ';',
· },
}

func (*ProcList) Pos

func (n *ProcList) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*ProcList) String

func (n *ProcList) String() string

String implements fmt.Stringer.

type ProcListOpt

type ProcListOpt struct {
	ProcList *ProcList
}

ProcListOpt represents data reduced by productions:

ProcListOpt:
        /* empty */
|       ProcList     // Case 1
Example
fmt.Println(exampleAST(17, "!") == (*ProcListOpt)(nil))
Output:

true
Example (Case1)
fmt.Println(exampleAST(18, "PROCEDURE a ; ; !"))
Output:

&pl0.ProcListOpt{
· ProcList: &pl0.ProcList{
· · ProcSpec: &pl0.ProcSpec{
· · · Block: &pl0.Block{
· · · },
· · · Token: example18.pl0:1:1: PROCEDURE,
· · · Token2: example18.pl0:1:11: IDENT "a",
· · · Token3: example18.pl0:1:13: ';',
· · · Token4: example18.pl0:1:15: ';',
· · },
· },
}

func (*ProcListOpt) Pos

func (n *ProcListOpt) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*ProcListOpt) String

func (n *ProcListOpt) String() string

String implements fmt.Stringer.

type ProcSpec

type ProcSpec struct {
	Block  *Block
	Token  xc.Token
	Token2 xc.Token
	Token3 xc.Token
	Token4 xc.Token
	// contains filtered or unexported fields
}

ProcSpec represents data reduced by production:

ProcSpec:
        "PROCEDURE" IDENT ';' Block ';'
Example
fmt.Println(exampleAST(22, "PROCEDURE a ; ; !"))
Output:

&pl0.ProcSpec{
· Block: &pl0.Block{
· },
· Token: example22.pl0:1:1: PROCEDURE,
· Token2: example22.pl0:1:11: IDENT "a",
· Token3: example22.pl0:1:13: ';',
· Token4: example22.pl0:1:15: ';',
}

func (*ProcSpec) Pos

func (n *ProcSpec) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*ProcSpec) String

func (n *ProcSpec) String() string

String implements fmt.Stringer.

type Program

type Program struct {
	Code  []Instruction
	Block *Block
	Token xc.Token
}

Program represents data reduced by production:

Program:
        Block '.'
Example
fmt.Println(exampleAST(1, "."))
Output:

&pl0.Program{
· Code: []*pl0.Call{ // len 5
· · 0: &pl0.Call{
· · · Target: 2,
· · },
· · 1: &pl0.Halt{
· · · Addr: 1,
· · },
· · 2: &pl0.Enter{
· · · Addr: 2,
· · · Token: example1.pl0:1:1: '.',
· · },
· · 3: &pl0.Jmp{
· · · Addr: 3,
· · · Target: 4,
· · },
· · 4: &pl0.Leave{
· · · Addr: 4,
· · },
· },
· Block: &pl0.Block{
· },
· Token: example1.pl0:1:1: '.',
}

func Parse

func Parse(nm string) (*Program, error)

Parse parses PL/0 source in nm and returns a *Program, or an error, if any. The returned error is either nil or it is guaranteed to be of type go/scanner.ErrorList.

func ParseString

func ParseString(nm, src string) (*Program, error)

ParseString is like Parse except the source code comes from a string.

func (*Program) List

func (n *Program) List(w io.Writer) error

List list n.Code to w.

func (*Program) Pos

func (n *Program) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*Program) Run

func (n *Program) Run(opts ...RunOption) error

Run executes n.Code. opts optionally ammend the VM used to execute the program.

func (*Program) String

func (n *Program) String() string

String implements fmt.Stringer.

type PushConst

type PushConst struct {
	Addr
	Value int
	Token xc.Token
}

PushConst is an Instruction pushing a constant on stack.

func (*PushConst) Execute

func (n *PushConst) Execute(m *VM)

Execute implements Instruction.

func (*PushConst) String

func (n *PushConst) String() string

String implements fmt.Stringer.

type PushVar

type PushVar struct {
	Addr
	Index  int
	Frames int
	Token  xc.Token
}

PushVar is an Instruction pushing a variable on stack.

func (*PushVar) Execute

func (n *PushVar) Execute(m *VM)

Execute implements Instruction.

func (*PushVar) String

func (n *PushVar) String() string

String implements fmt.Stringer.

type Read

type Read struct {
	Addr
	Index  int
	Frames int
	Token  xc.Token
}

Read is an Instruction setting a variable from user input.

func (*Read) Execute

func (n *Read) Execute(m *VM)

Execute implements Instruction.

func (*Read) String

func (n *Read) String() string

String implements fmt.Stringer.

type RunOption

type RunOption func(*VM) error

RunOption is an option of (*Program).Run.

func Trace

func Trace() RunOption

Trace turns on tracing of instructions executed.

func TraceStack

func TraceStack() RunOption

TraceStack turns on tracing of instructions executed and stack state.

type Statement

type Statement struct {
	Case          int
	Condition     *Condition
	Expression    *Expression
	Statement     *Statement
	StatementList *StatementList
	Token         xc.Token
	Token2        xc.Token
}

Statement represents data reduced by productions:

Statement:
        /* empty */
|       IDENT ":=" Expression             // Case 1
|       "CALL" IDENT                      // Case 2
|       '?' IDENT                         // Case 3
|       '!' Expression                    // Case 4
|       "BEGIN" StatementList "END"       // Case 5
|       "IF" Condition "THEN" Statement   // Case 6
|       "WHILE" Condition "DO" Statement  // Case 7
Example
fmt.Println(exampleAST(23, ".") == (*Statement)(nil))
Output:

true
Example (Case1)
fmt.Println(exampleAST(24, "a := b ."))
Output:

&pl0.Statement{
· Case: 1,
· Expression: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example24.pl0:1:6: IDENT "b",
· · · },
· · },
· },
· Token: example24.pl0:1:1: IDENT "a",
· Token2: example24.pl0:1:3: ASSIGN,
}
Example (Case2)
fmt.Println(exampleAST(25, "CALL a ."))
Output:

&pl0.Statement{
· Case: 2,
· Token: example25.pl0:1:1: CALL,
· Token2: example25.pl0:1:6: IDENT "a",
}
Example (Case3)
fmt.Println(exampleAST(26, "? a ."))
Output:

&pl0.Statement{
· Case: 3,
· Token: example26.pl0:1:1: '?',
· Token2: example26.pl0:1:3: IDENT "a",
}
Example (Case4)
fmt.Println(exampleAST(27, "! a ."))
Output:

&pl0.Statement{
· Case: 4,
· Expression: &pl0.Expression{
· · Case: 2,
· · Term: &pl0.Term{
· · · Factor: &pl0.Factor{
· · · · Token: example27.pl0:1:3: IDENT "a",
· · · },
· · },
· },
· Token: example27.pl0:1:1: '!',
}
Example (Case5)
fmt.Println(exampleAST(28, "BEGIN END ."))
Output:

&pl0.Statement{
· Case: 5,
· Token: example28.pl0:1:1: BEGIN,
· Token2: example28.pl0:1:7: END,
}
Example (Case6)
fmt.Println(exampleAST(30, "IF ODD a THEN ."))
Output:

&pl0.Statement{
· Case: 6,
· Condition: &pl0.Condition{
· · Expression: &pl0.Expression{
· · · Case: 2,
· · · Term: &pl0.Term{
· · · · Factor: &pl0.Factor{
· · · · · Token: example30.pl0:1:8: IDENT "a",
· · · · },
· · · },
· · },
· · Token: example30.pl0:1:4: ODD,
· },
· Token: example30.pl0:1:1: IF,
· Token2: example30.pl0:1:10: THEN,
}
Example (Case7)
fmt.Println(exampleAST(33, "WHILE ODD a DO ."))
Output:

&pl0.Statement{
· Case: 7,
· Condition: &pl0.Condition{
· · Expression: &pl0.Expression{
· · · Case: 2,
· · · Term: &pl0.Term{
· · · · Factor: &pl0.Factor{
· · · · · Token: example33.pl0:1:11: IDENT "a",
· · · · },
· · · },
· · },
· · Token: example33.pl0:1:7: ODD,
· },
· Token: example33.pl0:1:1: WHILE,
· Token2: example33.pl0:1:13: DO,
}

func (*Statement) Pos

func (n *Statement) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*Statement) String

func (n *Statement) String() string

String implements fmt.Stringer.

type StatementList

type StatementList struct {
	Case          int
	Statement     *Statement
	StatementList *StatementList
	Token         xc.Token
}

StatementList represents data reduced by productions:

StatementList:
        Statement
|       StatementList ';' Statement  // Case 1
Example
fmt.Println(exampleAST(34, "BEGIN i := 42 END"))
Output:

&pl0.StatementList{
· Statement: &pl0.Statement{
· · Case: 1,
· · Expression: &pl0.Expression{
· · · Case: 2,
· · · Term: &pl0.Term{
· · · · Factor: &pl0.Factor{
· · · · · Case: 1,
· · · · · Number: &pl0.Number{
· · · · · · Value: 42,
· · · · · · Token: example34.pl0:1:12: NUMBER "42",
· · · · · },
· · · · },
· · · },
· · },
· · Token: example34.pl0:1:7: IDENT "i",
· · Token2: example34.pl0:1:9: ASSIGN,
· },
}
Example (Case1)
fmt.Println(exampleAST(35, "BEGIN ; ;"))
Output:

&pl0.StatementList{
· StatementList: &pl0.StatementList{
· · Case: 1,
· · Token: example35.pl0:1:7: ';',
· },
}

func (*StatementList) Pos

func (n *StatementList) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*StatementList) String

func (n *StatementList) String() string

String implements fmt.Stringer.

type Sub

type Sub struct {
	Addr
	Token xc.Token
}

Sub is an Instruction producing the difference of the top two stack items.

func (*Sub) Execute

func (n *Sub) Execute(m *VM)

Execute implements Instruction.

func (*Sub) String

func (n *Sub) String() string

String implements fmt.Stringer.

type Term

type Term struct {
	Case   int
	Factor *Factor
	Term   *Term
	Token  xc.Token
}

Term represents data reduced by productions:

Term:
        Factor
|       Term '*' Factor  // Case 1
|       Term '/' Factor  // Case 2
Example
fmt.Println(exampleAST(48, "IF a #"))
Output:

&pl0.Term{
· Factor: &pl0.Factor{
· · Token: example48.pl0:1:4: IDENT "a",
· },
}
Example (Case1)
fmt.Println(exampleAST(49, "IF a * b #"))
Output:

&pl0.Term{
· Case: 1,
· Factor: &pl0.Factor{
· · Token: example49.pl0:1:8: IDENT "b",
· },
· Term: &pl0.Term{
· · Factor: &pl0.Factor{
· · · Token: example49.pl0:1:4: IDENT "a",
· · },
· },
· Token: example49.pl0:1:6: '*',
}
Example (Case2)
fmt.Println(exampleAST(50, "IF a / b #"))
Output:

&pl0.Term{
· Case: 2,
· Factor: &pl0.Factor{
· · Token: example50.pl0:1:8: IDENT "b",
· },
· Term: &pl0.Term{
· · Factor: &pl0.Factor{
· · · Token: example50.pl0:1:4: IDENT "a",
· · },
· },
· Token: example50.pl0:1:6: '/',
}

func (*Term) Pos

func (n *Term) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*Term) String

func (n *Term) String() string

String implements fmt.Stringer.

type TestEQ

type TestEQ struct {
	Addr
	Token xc.Token
}

TestEQ is an Instruction testing equality of the top two stack items.

func (*TestEQ) Execute

func (n *TestEQ) Execute(m *VM)

Execute implements Instruction.

func (*TestEQ) String

func (n *TestEQ) String() string

String implements fmt.Stringer.

type TestGEQ

type TestGEQ struct {
	Addr
	Token xc.Token
}

TestGEQ is an Instruction testing >= of the top two stack items.

func (*TestGEQ) Execute

func (n *TestGEQ) Execute(m *VM)

Execute implements Instruction.

func (*TestGEQ) String

func (n *TestGEQ) String() string

String implements fmt.Stringer.

type TestGT

type TestGT struct {
	Addr
	Token xc.Token
}

TestGT is an Instruction testing > of the top two stack items.

func (*TestGT) Execute

func (n *TestGT) Execute(m *VM)

Execute implements Instruction.

func (*TestGT) String

func (n *TestGT) String() string

String implements fmt.Stringer.

type TestLEQ

type TestLEQ struct {
	Addr
	Token xc.Token
}

TestLEQ is an Instruction testing <= of the top two stack items.

func (*TestLEQ) Execute

func (n *TestLEQ) Execute(m *VM)

Execute implements Instruction.

func (*TestLEQ) String

func (n *TestLEQ) String() string

String implements fmt.Stringer.

type TestLT

type TestLT struct {
	Addr
	Token xc.Token
}

TestLT is an Instruction testing < of the top two stack items.

func (*TestLT) Execute

func (n *TestLT) Execute(m *VM)

Execute implements Instruction.

func (*TestLT) String

func (n *TestLT) String() string

String implements fmt.Stringer.

type TestMod

type TestMod struct {
	Addr
	Token xc.Token
}

TestMod is an Instruction testing if the top two stack items have non zero reminder on division.

func (*TestMod) Execute

func (n *TestMod) Execute(m *VM)

Execute implements Instruction.

func (*TestMod) String

func (n *TestMod) String() string

String implements fmt.Stringer.

type TestOdd

type TestOdd struct {
	Addr
	Token xc.Token
}

TestOdd is an Instruction testing if TOS&1 != 0.

func (*TestOdd) Execute

func (n *TestOdd) Execute(m *VM)

Execute implements Instruction.

func (*TestOdd) String

func (n *TestOdd) String() string

String implements fmt.Stringer.

type VM

type VM struct {
	Code       []Instruction
	FP         int
	Halted     bool
	IP         int
	Stack      []int
	Stdin      io.Reader
	Stdout     io.Writer
	T          int
	Trace      bool
	TraceStack bool
}

VM is PL/0 virtual machine.

func NewVM

func NewVM(stdin io.Reader, stdout io.Writer, code []Instruction) *VM

NewVM returns a newly created VM.

func (*VM) Run

func (m *VM) Run() (err error)

Run executes m.Code.

func (*VM) SP

func (m *VM) SP() int

SP returns the stack pointer of m.

func (*VM) Step

func (m *VM) Step() (err error)

Step executes on instruction of m.

type Variable

type Variable struct {
	Token xc.Token
	// contains filtered or unexported fields
}

Variable represents data reduced by production:

Variable:
        IDENT
Example
fmt.Println(exampleAST(14, "VAR a ,"))
Output:

&pl0.Variable{
· Token: example14.pl0:1:5: IDENT "a",
}

func (*Variable) Pos

func (n *Variable) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*Variable) String

func (n *Variable) String() string

String implements fmt.Stringer.

type VariableList

type VariableList struct {
	Case         int
	Token        xc.Token
	Variable     *Variable
	VariableList *VariableList
}

VariableList represents data reduced by productions:

VariableList:
        Variable
|       VariableList ',' Variable  // Case 1
Example
fmt.Println(exampleAST(15, "VAR a ,"))
Output:

&pl0.VariableList{
· Variable: &pl0.Variable{
· · Token: example15.pl0:1:5: IDENT "a",
· },
}
Example (Case1)
fmt.Println(exampleAST(16, "VAR a , b ,"))
Output:

&pl0.VariableList{
· Variable: &pl0.Variable{
· · Token: example16.pl0:1:5: IDENT "a",
· },
· VariableList: &pl0.VariableList{
· · Case: 1,
· · Token: example16.pl0:1:7: ',',
· · Variable: &pl0.Variable{
· · · Token: example16.pl0:1:9: IDENT "b",
· · },
· },
}

func (*VariableList) Pos

func (n *VariableList) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*VariableList) String

func (n *VariableList) String() string

String implements fmt.Stringer.

type Vars

type Vars struct {
	Token        xc.Token
	Token2       xc.Token
	VariableList *VariableList
	// contains filtered or unexported fields
}

Vars represents data reduced by production:

Vars:
        "VAR" VariableList ';'
Example
fmt.Println(exampleAST(13, "VAR a ; !"))
Output:

&pl0.Vars{
· Token: example13.pl0:1:1: VAR,
· Token2: example13.pl0:1:7: ';',
· VariableList: &pl0.VariableList{
· · Variable: &pl0.Variable{
· · · Token: example13.pl0:1:5: IDENT "a",
· · },
· },
}

func (*Vars) Pos

func (n *Vars) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*Vars) String

func (n *Vars) String() string

String implements fmt.Stringer.

type VarsOpt

type VarsOpt struct {
	Vars *Vars
}

VarsOpt represents data reduced by productions:

VarsOpt:
        /* empty */
|       Vars         // Case 1
Example
fmt.Println(exampleAST(11, "!") == (*VarsOpt)(nil))
Output:

true
Example (Case1)
fmt.Println(exampleAST(12, "VAR a ; !"))
Output:

&pl0.VarsOpt{
· Vars: &pl0.Vars{
· · Token: example12.pl0:1:1: VAR,
· · Token2: example12.pl0:1:7: ';',
· · VariableList: &pl0.VariableList{
· · · Variable: &pl0.Variable{
· · · · Token: example12.pl0:1:5: IDENT "a",
· · · },
· · },
· },
}

func (*VarsOpt) Pos

func (n *VarsOpt) Pos() token.Pos

Pos reports the position of the first component of n or zero if it's empty.

func (*VarsOpt) String

func (n *VarsOpt) String() string

String implements fmt.Stringer.

type Write

type Write struct {
	Addr
	Token xc.Token
}

Write is an Instruction writing TOS to VM.Stdout.

func (*Write) Execute

func (n *Write) Execute(m *VM)

Execute implements Instruction.

func (*Write) String

func (n *Write) String() string

String implements fmt.Stringer.

Directories

Path Synopsis
Command pl0 compiles and executes pl0[0] programs.
Command pl0 compiles and executes pl0[0] programs.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL