From 500caaeda74dd9c660279036293f4b2997cf0b03 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Sat, 9 Sep 2017 09:42:37 +0200 Subject: Add vendor --- vendor/github.com/llgcode/ps/interpreter.go | 312 ++++++++++++++++++++++++++++ 1 file changed, 312 insertions(+) create mode 100644 vendor/github.com/llgcode/ps/interpreter.go (limited to 'vendor/github.com/llgcode/ps/interpreter.go') diff --git a/vendor/github.com/llgcode/ps/interpreter.go b/vendor/github.com/llgcode/ps/interpreter.go new file mode 100644 index 0000000..63662a0 --- /dev/null +++ b/vendor/github.com/llgcode/ps/interpreter.go @@ -0,0 +1,312 @@ +// Copyright 2010 The postscript-go Authors. All rights reserved. +// created: 13/12/2010 by Laurent Le Goff + +package ps + +import ( + "io" + "log" + "os" + "strconv" + + "github.com/llgcode/draw2d" +) + +type Interpreter struct { + valueStack ValueStack + dictionaryStack DictionaryStack + gc draw2d.GraphicContext +} + +type Value interface{} + +type ValueStack []Value + +type Dictionary map[string]Value + +type DictionaryStack []Dictionary + +type Operator interface { + Execute(interpreter *Interpreter) +} + +func NewInterpreter(gc draw2d.GraphicContext) *Interpreter { + interpreter := new(Interpreter) + interpreter.valueStack = make([]Value, 0, 100) + interpreter.dictionaryStack = make([]Dictionary, 2, 10) + interpreter.dictionaryStack[0] = NewDictionary(100) // System dictionary + interpreter.dictionaryStack[1] = NewDictionary(100) // user dictionary + initSystemOperators(interpreter) + interpreter.gc = gc + return interpreter +} + +func NewDictionary(prealloc int) Dictionary { + return make(Dictionary, prealloc) +} + +func (interpreter *Interpreter) SetGraphicContext(gc draw2d.GraphicContext) { + interpreter.gc = gc +} + +func (interpreter *Interpreter) GetGraphicContext() draw2d.GraphicContext { + return interpreter.gc +} +func (interpreter *Interpreter) Execute(reader io.Reader) { + var scanner Scanner + scanner.Init(reader) + token := scanner.Scan() + for token != EOF { + interpreter.scan(&scanner, token) + token = scanner.Scan() + } +} + +func (interpreter *Interpreter) ExecuteFile(filePath string) error { + src, err := os.Open(filePath) + if src == nil { + log.Printf("can't open file; err=%s\n", err.Error()) + return err + } + defer src.Close() + interpreter.Execute(src) + return nil +} +func (interpreter *Interpreter) computeReference(ref string) { + value, _ := interpreter.FindValueInDictionaries(ref) + if value == nil { + log.Printf("Unknown def: %s\n", ref) + } else { + operator, isOperator := value.(Operator) + if isOperator { + operator.Execute(interpreter) + } else { + interpreter.Push(value) + } + } +} +func (interpreter *Interpreter) scan(scanner *Scanner, token int) { + if token == Ident { + switch scanner.TokenText() { + case "true": + interpreter.Push(true) + case "false": + interpreter.Push(false) + case "null": + interpreter.Push(nil) + default: + interpreter.computeReference(scanner.TokenText()) + } + } else if token == '/' { + scanner.Scan() + interpreter.Push("/" + scanner.TokenText()) + } else if token == '[' { + interpreter.Push(interpreter.scanArray(scanner)) + } else if token == '{' { + // procedure + interpreter.Push(interpreter.scanProcedure(scanner)) + } else if token == Float || token == Int { + f, err := strconv.ParseFloat(scanner.TokenText(), 64) + if err != nil { + log.Printf("Float expected: %s\n", scanner.TokenText()) + interpreter.Push(scanner.TokenText()) + } else { + interpreter.Push(f) + } + } else { + interpreter.Push(scanner.TokenText()) + } +} + +func (interpreter *Interpreter) scanArray(scanner *Scanner) []Value { + array := make([]Value, 0, 10) + token := scanner.Scan() + for token != EOF && token != ']' { + if token == Ident { + var v Value = scanner.TokenText() + switch scanner.TokenText() { + case "true": + v = true + case "false": + v = false + case "null": + v = nil + } + array = append(array, v) + } else { + interpreter.scan(scanner, token) + array = append(array, interpreter.Pop()) + } + token = scanner.Scan() + } + return array +} + +func (interpreter *Interpreter) scanProcedure(scanner *Scanner) *ProcedureDefinition { + proceduredef := NewProcedureDefinition() + token := scanner.Scan() + for token != EOF && token != '}' { + if token == Ident { + var v Value = scanner.TokenText() + switch scanner.TokenText() { + case "true": + v = true + case "false": + v = false + case "null": + v = nil + } + proceduredef.Add(v) + } else { + interpreter.scan(scanner, token) + proceduredef.Add(interpreter.Pop()) + } + token = scanner.Scan() + } + return proceduredef +} + +//Dictionary Operation + +func (interpreter *Interpreter) PushDictionary(dictionary Dictionary) { + interpreter.dictionaryStack = append(interpreter.dictionaryStack, dictionary) +} + +func (interpreter *Interpreter) PopDictionary() Dictionary { + stackPointer := len(interpreter.dictionaryStack) - 1 + dictionary := interpreter.dictionaryStack[stackPointer] + interpreter.dictionaryStack = interpreter.dictionaryStack[0:stackPointer] + return dictionary +} + +func (interpreter *Interpreter) PeekDictionary() Dictionary { + stackPointer := len(interpreter.dictionaryStack) - 1 + return interpreter.dictionaryStack[stackPointer] +} +func (interpreter *Interpreter) ClearDictionaries() { + interpreter.dictionaryStack = interpreter.dictionaryStack[:2] +} + +func (interpreter *Interpreter) DictionaryStackSize() int { + return len(interpreter.dictionaryStack) +} + +func (interpreter *Interpreter) FindValue(name string) Value { + return interpreter.PeekDictionary()[name] +} + +func (interpreter *Interpreter) FindValueInDictionaries(name string) (Value, Dictionary) { + for i := len(interpreter.dictionaryStack) - 1; i >= 0; i-- { + value := interpreter.dictionaryStack[i][name] + if value != nil { + return value, interpreter.dictionaryStack[i] + } + } + return nil, nil +} + +func (interpreter *Interpreter) UserDictionary() Dictionary { + return interpreter.dictionaryStack[0] +} + +func (interpreter *Interpreter) SystemDictionary() Dictionary { + return interpreter.dictionaryStack[0] +} + +func (interpreter *Interpreter) Define(name string, value Value) { + interpreter.PeekDictionary()[name] = value +} + +func (interpreter *Interpreter) SystemDefine(name string, value Value) { + interpreter.dictionaryStack[0][name] = value +} + +//Operand Operation + +func (interpreter *Interpreter) Push(operand Value) { + //log.Printf("Push operand: %v\n", operand) + interpreter.valueStack = append(interpreter.valueStack, operand) +} + +func (interpreter *Interpreter) Pop() Value { + valueStackPointer := len(interpreter.valueStack) - 1 + operand := interpreter.valueStack[valueStackPointer] + interpreter.valueStack = interpreter.valueStack[0:valueStackPointer] + //log.Printf("Pop operand: %v\n", operand) + return operand +} + +func (interpreter *Interpreter) PopValues(n int) []Value { + valueStackPointer := len(interpreter.valueStack) - 1 + operands := make([]Value, n) + copy(operands, interpreter.valueStack[valueStackPointer-n+1:valueStackPointer+1]) + interpreter.valueStack = interpreter.valueStack[0 : valueStackPointer-n+1] + return operands +} + +func (interpreter *Interpreter) GetValues(n int) []Value { + valueStackPointer := len(interpreter.valueStack) - 1 + operands := make([]Value, n) + copy(operands, interpreter.valueStack[valueStackPointer-n+1:valueStackPointer+1]) + return operands +} + +func (interpreter *Interpreter) Get(index int) Value { + valueStackPointer := len(interpreter.valueStack) - 1 + return interpreter.valueStack[valueStackPointer-index] +} + +func (interpreter *Interpreter) Peek() Value { + valueStackPointer := len(interpreter.valueStack) - 1 + return interpreter.valueStack[valueStackPointer] +} + +func (interpreter *Interpreter) OperandSize() int { + return len(interpreter.valueStack) +} + +func (interpreter *Interpreter) ClearOperands() { + interpreter.valueStack = interpreter.valueStack[0:0] +} + +// misc pop + +func (interpreter *Interpreter) PopFloat() float64 { + operand := interpreter.Pop() + return operand.(float64) +} + +func (interpreter *Interpreter) PopInt() int { + f := interpreter.PopFloat() + return int(f) +} + +func (interpreter *Interpreter) PopOperator() Operator { + operator := interpreter.Pop() + return operator.(Operator) +} + +func (interpreter *Interpreter) PopProcedureDefinition() *ProcedureDefinition { + def := interpreter.Pop() + return def.(*ProcedureDefinition) +} + +func (interpreter *Interpreter) PopName() string { + name := interpreter.Pop().(string) + return name[1:] +} + +func (interpreter *Interpreter) PopString() string { + s := interpreter.Pop().(string) + return s[1 : len(s)-1] +} + +func (interpreter *Interpreter) PopBoolean() bool { + s := interpreter.Pop() + return s.(bool) +} + +func (interpreter *Interpreter) PopArray() []Value { + s := interpreter.Pop() + return s.([]Value) +} -- cgit v1.2.3