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 ¶
- Constants
- func PrettyString(v interface{}) string
- type Add
- type Addr
- type Binding
- type Bindings
- type Block
- type Call
- type Condition
- type ConstSpec
- type ConstSpecList
- type Consts
- type ConstsOpt
- type Div
- type Enter
- type Expression
- type Factor
- type Halt
- type Instruction
- type Jmp
- type JmpZero
- type Leave
- type Mul
- type Neg
- type Node
- type Number
- type PopVar
- type ProcList
- type ProcListOpt
- type ProcSpec
- type Program
- type PushConst
- type PushVar
- type Read
- type RunOption
- type Statement
- type StatementList
- type Sub
- type Term
- type TestEQ
- type TestGEQ
- type TestGT
- type TestLEQ
- type TestLT
- type TestMod
- type TestOdd
- type VM
- type Variable
- type VariableList
- type Vars
- type VarsOpt
- type Write
Examples ¶
- Package (IllegalAssignment)
- Package (IllegalCall)
- Package (IllegalFactor)
- Package (IllegalRead)
- Package (List)
- Package (Program1)
- Package (Program2)
- Package (Redeclaration)
- Package (StackFrames)
- Package (StackTrace)
- Package (Trace)
- Package (Undeclared)
- Block
- Condition
- Condition (Case1)
- Condition (Case2)
- Condition (Case3)
- Condition (Case4)
- Condition (Case5)
- Condition (Case6)
- ConstSpec
- ConstSpecList
- ConstSpecList (Case1)
- Consts
- ConstsOpt
- ConstsOpt (Case1)
- Expression
- Expression (Case1)
- Expression (Case2)
- Expression (Case3)
- Expression (Case4)
- Factor
- Factor (Case1)
- Factor (Case2)
- Number
- ProcList
- ProcList (Case1)
- ProcListOpt
- ProcListOpt (Case1)
- ProcSpec
- Program
- Statement
- Statement (Case1)
- Statement (Case2)
- Statement (Case3)
- Statement (Case4)
- Statement (Case5)
- Statement (Case6)
- Statement (Case7)
- StatementList
- StatementList (Case1)
- Term
- Term (Case1)
- Term (Case2)
- Variable
- VariableList
- VariableList (Case1)
- Vars
- VarsOpt
- VarsOpt (Case1)
Constants ¶
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 Bindings ¶
type Bindings struct { Map map[int]*Binding Parent *Bindings // contains filtered or unexported fields }
Bindings capture name -> Binding projections in a scope.
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", · }, }
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, }
type ConstSpec ¶
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: '=', }
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: ';', }
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: ';', · }, }
type Enter ¶
Enter is an Instruction setting up VM.FP and the stack frame upon entry to a subroutine.
func (*Enter) Execute ¶
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
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.
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: ')', }
type Instruction ¶
Instruction must be implemented by all instructions of VM.
type Leave ¶
type Leave struct {
Addr
}
Leave is an Instruction restoring the stack frame and IP prior to a subroutine call.
type Number ¶
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", }
type ProcList ¶
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: ';', · }, }
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.
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: ';', }
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 ¶
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 ¶
ParseString is like Parse except the source code comes from a string.
type RunOption ¶
RunOption is an option of (*Program).Run.
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, }
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 Term ¶
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: '/', }
type TestMod ¶
TestMod is an Instruction testing if the top two stack items have non zero reminder on division.
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.
type Variable ¶
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", }
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", · · }, · }, }
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", · · · }, · · }, · }, }