/// <summary> /// Bind the operand /// </summary> public override void Bind(EpsInterpreter interpreter) { var name = new NameOperand { Value = this.Name }; BoundOperand = DictionaryStackHelper.FindValue(interpreter.DictionaryStack, name); }
public override void Execute(EpsInterpreter interpreter) { var name = new NameOperand { Value = this.Name }; var op = DictionaryStackHelper.FindValue(interpreter.DictionaryStack, name); interpreter.OperandStack.Push(op); }
public override void Execute(EpsInterpreter interpreter) { var operandStack = interpreter.OperandStack; var operand = operandStack.Pop(); var op = new NameOperand(operand.TypeName); op.IsExecutable = true; operandStack.Push(op); }
public override void Execute(EpsInterpreter interpreter) { var dict = new EpsDictionary(); var name = new NameOperand { Value = "MaxPatternCache" }; var someValue = new IntegerOperand { Value = 42 }; dict.Add(name, someValue); interpreter.OperandStack.Push(new DictionaryOperand(dict)); }
/// <summary> /// Execute the operand /// </summary> public override void Execute(EpsInterpreter interpreter) { if (interpreter.BreakCurrentLoop) { return; } if (BoundOperand != null) { interpreter.Execute(BoundOperand); } else { var name = new NameOperand { Value = this.Name }; var op = DictionaryStackHelper.FindValue(interpreter.DictionaryStack, name); if (op != null) { interpreter.Execute(op); } else { // Throwing an exception when the interpreter is within a stopped context // would also be ok and is the prefered behavior. We test for the stopped // context here to make debugging a bit easier. So that the debugger // doesn't stop when the "exception" is handled in the postscript script, // e.g. when tests are made if a command is available. if (!interpreter.IsInStoppedContext) { throw new Exception($"unknown command \"{Name}\""); } interpreter.StopProcedure(); } } }
/// <summary> /// Gets the next operand /// </summary> public Operand GetNextOperand() { var symbol = lexer.ScanNextToken(reader); switch (symbol) { case LexerToken.Eof: { return(null); } case LexerToken.DscComment: { // We handle each comment that starts at the beginning of a // line as a dsc comment. That enables us to handle some // special Illustrator comments. DscCommentOperand dscOp = new DscCommentOperand(); dscOp.LineNumber = reader.LineNumber; dscOp.Name = lexer.StringToken; if (!reader.IsAtEndOfLine) { // The number and types and syntax of the parameters depend // on the dsc comment and vary pretty much. That's why we // cannot scan and parse the parameters here. Just pass the // pure rest of the line to the dsc comment, it needs to do // the rest :-( var restOfLine = reader.ReadLine(); dscOp.Parameters = restOfLine.Trim(); } return(dscOp); } case LexerToken.Integer: { IntegerOperand n = new IntegerOperand(); n.LineNumber = reader.LineNumber; n.Value = lexer.IntegerToken; return(n); } case LexerToken.Real: { RealOperand r = new RealOperand(); r.LineNumber = reader.LineNumber; r.Value = lexer.RealToken; return(r); } case LexerToken.String: { var s = new StringOperand(); s.LineNumber = reader.LineNumber; s.Value = lexer.StringToken; s.Type = StringType.Standard; return(s); } case LexerToken.HexString: { var s = new StringOperand(); s.LineNumber = reader.LineNumber; s.Value = lexer.StringToken; s.Type = StringType.Hex; return(s); } case LexerToken.AsciiBase85String: { var s = new StringOperand(); s.LineNumber = reader.LineNumber; s.Value = lexer.StringToken; s.Type = StringType.AsciiBase85; return(s); } case LexerToken.Name: { NameOperand name = new NameOperand(); name.LineNumber = reader.LineNumber; name.Value = lexer.StringToken; return(name); } case LexerToken.Operator: { var op = new OperatorOperand(); op.LineNumber = reader.LineNumber; op.Name = lexer.StringToken; return(op); } case LexerToken.ImmediateOperator: { var op = new ImmediateOperand(); op.LineNumber = reader.LineNumber; op.Name = lexer.StringToken; return(op); } case LexerToken.BeginDictionary: { var op = new MarkOperand(); op.LineNumber = reader.LineNumber; return(op); } case LexerToken.EndDictionary: { var op = new EndDictionaryOperand(); op.LineNumber = reader.LineNumber; return(op); } case LexerToken.BeginArray: { var op = new MarkOperand(); op.LineNumber = reader.LineNumber; return(op); } case LexerToken.EndArray: { var op = new EndArrayOperand(); op.LineNumber = reader.LineNumber; return(op); } case LexerToken.BeginProcedure: { var op = new BeginProcedureOperand(); op.LineNumber = reader.LineNumber; return(op); } case LexerToken.EndProcedure: { var op = new EndProcedureOperand(); op.LineNumber = reader.LineNumber; return(op); } default: throw new Exception("unhandled token"); } }