aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/llgcode/ps/operators_control.go
blob: 1aa411c372c33b3e831e95e688b34b5d40bc7f5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Copyright 2010 The postscript-go Authors. All rights reserved.
// created: 13/12/2010 by Laurent Le Goff

package ps

import (
	"log"
)

// any exec – Execute arbitrary object
func exec(interpreter *Interpreter) {
	value := interpreter.Pop()
	if pdef, ok := value.(*ProcedureDefinition); ok {
		NewProcedure(pdef).Execute(interpreter)
	} else if procedure, ok := value.(*Procedure); ok {
		procedure.Execute(interpreter)
	} else {
		log.Printf("Push value: %v\n", value)
		interpreter.Push(value)
	}
}

func ifoperator(interpreter *Interpreter) {
	operator := NewProcedure(interpreter.PopProcedureDefinition())
	condition := interpreter.PopBoolean()
	if condition {
		operator.Execute(interpreter)
	}
}

func ifelse(interpreter *Interpreter) {
	operator2 := NewProcedure(interpreter.PopProcedureDefinition())
	operator1 := NewProcedure(interpreter.PopProcedureDefinition())
	condition := interpreter.PopBoolean()
	if condition {
		operator1.Execute(interpreter)
	} else {
		operator2.Execute(interpreter)
	}
}

func foroperator(interpreter *Interpreter) {
	proc := NewProcedure(interpreter.PopProcedureDefinition())
	limit := interpreter.PopFloat()
	inc := interpreter.PopFloat()
	initial := interpreter.PopFloat()

	for i := initial; i <= limit; i += inc {
		interpreter.Push(i)
		proc.Execute(interpreter)
	}
}

func repeat(interpreter *Interpreter) {
	proc := NewProcedure(interpreter.PopProcedureDefinition())
	times := interpreter.PopInt()
	for i := 0; i <= times; i++ {
		proc.Execute(interpreter)
	}
}

// any stopped bool -> Establish context for catching stop
func stopped(interpreter *Interpreter) {
	value := interpreter.Pop()
	if pdef, ok := value.(*ProcedureDefinition); ok {
		NewProcedure(pdef).Execute(interpreter)
	} else {
		interpreter.Push(value)
	}
	interpreter.Push(false)
}

func initControlOperators(interpreter *Interpreter) {
	interpreter.SystemDefine("exec", NewOperator(exec))
	interpreter.SystemDefine("if", NewOperator(ifoperator))
	interpreter.SystemDefine("ifelse", NewOperator(ifelse))
	interpreter.SystemDefine("for", NewOperator(foroperator))
	interpreter.SystemDefine("repeat", NewOperator(repeat))
	interpreter.SystemDefine("stopped", NewOperator(stopped))
}