@@ -65,6 +65,7 @@ type Command struct {
65
65
Type CommandType
66
66
Options string
67
67
Args string
68
+ Source string
68
69
}
69
70
70
71
// String returns the string representation of the command.
@@ -123,15 +124,15 @@ func (p *Parser) Parse() []Command {
123
124
p .nextToken ()
124
125
continue
125
126
}
126
- cmds = append (cmds , p .parseCommand ())
127
+ cmds = append (cmds , p .parseCommand ()... )
127
128
p .nextToken ()
128
129
}
129
130
130
131
return cmds
131
132
}
132
133
133
134
// parseCommand parses a command.
134
- func (p * Parser ) parseCommand () Command {
135
+ func (p * Parser ) parseCommand () [] Command {
135
136
switch p .cur .Type {
136
137
case token .SPACE ,
137
138
token .BACKSPACE ,
@@ -146,42 +147,42 @@ func (p *Parser) parseCommand() Command {
146
147
token .UP ,
147
148
token .PAGE_UP ,
148
149
token .PAGE_DOWN :
149
- return p .parseKeypress (p .cur .Type )
150
+ return [] Command { p .parseKeypress (p .cur .Type )}
150
151
case token .SET :
151
- return p .parseSet ()
152
+ return [] Command { p .parseSet ()}
152
153
case token .OUTPUT :
153
- return p .parseOutput ()
154
+ return [] Command { p .parseOutput ()}
154
155
case token .SLEEP :
155
- return p .parseSleep ()
156
+ return [] Command { p .parseSleep ()}
156
157
case token .TYPE :
157
- return p .parseType ()
158
+ return [] Command { p .parseType ()}
158
159
case token .CTRL :
159
- return p .parseCtrl ()
160
+ return [] Command { p .parseCtrl ()}
160
161
case token .ALT :
161
- return p .parseAlt ()
162
+ return [] Command { p .parseAlt ()}
162
163
case token .SHIFT :
163
- return p .parseShift ()
164
+ return [] Command { p .parseShift ()}
164
165
case token .HIDE :
165
- return p .parseHide ()
166
+ return [] Command { p .parseHide ()}
166
167
case token .REQUIRE :
167
- return p .parseRequire ()
168
+ return [] Command { p .parseRequire ()}
168
169
case token .SHOW :
169
- return p .parseShow ()
170
+ return [] Command { p .parseShow ()}
170
171
case token .WAIT :
171
- return p .parseWait ()
172
+ return [] Command { p .parseWait ()}
172
173
case token .SOURCE :
173
174
return p .parseSource ()
174
175
case token .SCREENSHOT :
175
- return p .parseScreenshot ()
176
+ return [] Command { p .parseScreenshot ()}
176
177
case token .COPY :
177
- return p .parseCopy ()
178
+ return [] Command { p .parseCopy ()}
178
179
case token .PASTE :
179
- return p .parsePaste ()
180
+ return [] Command { p .parsePaste ()}
180
181
case token .ENV :
181
- return p .parseEnv ()
182
+ return [] Command { p .parseEnv ()}
182
183
default :
183
184
p .errors = append (p .errors , NewError (p .cur , "Invalid command: " + p .cur .Literal ))
184
- return Command {Type : token .ILLEGAL }
185
+ return [] Command {{ Type : token .ILLEGAL } }
185
186
}
186
187
}
187
188
@@ -659,13 +660,13 @@ func (p *Parser) parseEnv() Command {
659
660
// Source command takes a tape path to include in current tape.
660
661
//
661
662
// Source <path>
662
- func (p * Parser ) parseSource () Command {
663
+ func (p * Parser ) parseSource () [] Command {
663
664
cmd := Command {Type : token .SOURCE }
664
665
665
666
if p .peek .Type != token .STRING {
666
667
p .errors = append (p .errors , NewError (p .cur , "Expected path after Source" ))
667
668
p .nextToken ()
668
- return cmd
669
+ return [] Command { cmd }
669
670
}
670
671
671
672
srcPath := p .peek .Literal
@@ -675,15 +676,15 @@ func (p *Parser) parseSource() Command {
675
676
if ext != ".tape" {
676
677
p .errors = append (p .errors , NewError (p .peek , "Expected file with .tape extension" ))
677
678
p .nextToken ()
678
- return cmd
679
+ return [] Command { cmd }
679
680
}
680
681
681
682
// Check if tape exist
682
683
if _ , err := os .Stat (srcPath ); os .IsNotExist (err ) {
683
684
notFoundErr := fmt .Sprintf ("File %s not found" , srcPath )
684
685
p .errors = append (p .errors , NewError (p .peek , notFoundErr ))
685
686
p .nextToken ()
686
- return cmd
687
+ return [] Command { cmd }
687
688
}
688
689
689
690
// Check if source tape contains nested Source command
@@ -692,7 +693,7 @@ func (p *Parser) parseSource() Command {
692
693
readErr := fmt .Sprintf ("Unable to read file: %s" , srcPath )
693
694
p .errors = append (p .errors , NewError (p .peek , readErr ))
694
695
p .nextToken ()
695
- return cmd
696
+ return [] Command { cmd }
696
697
}
697
698
698
699
srcTape := string (d )
@@ -701,7 +702,7 @@ func (p *Parser) parseSource() Command {
701
702
readErr := fmt .Sprintf ("Source tape: %s is empty" , srcPath )
702
703
p .errors = append (p .errors , NewError (p .peek , readErr ))
703
704
p .nextToken ()
704
- return cmd
705
+ return [] Command { cmd }
705
706
}
706
707
707
708
srcLexer := lexer .New (srcTape )
@@ -713,7 +714,7 @@ func (p *Parser) parseSource() Command {
713
714
if cmd .Type == token .SOURCE {
714
715
p .errors = append (p .errors , NewError (p .peek , "Nested Source detected" ))
715
716
p .nextToken ()
716
- return cmd
717
+ return [] Command { cmd }
717
718
}
718
719
}
719
720
@@ -722,12 +723,23 @@ func (p *Parser) parseSource() Command {
722
723
if len (srcErrors ) > 0 {
723
724
p .errors = append (p .errors , NewError (p .peek , fmt .Sprintf ("%s has %d errors" , srcPath , len (srcErrors ))))
724
725
p .nextToken ()
725
- return cmd
726
+ return [] Command { cmd }
726
727
}
727
728
728
729
cmd .Args = p .peek .Literal
730
+ filtered := make ([]Command , 0 )
731
+ for _ , srcCmd := range srcCmds {
732
+ // Output have to be avoid in order to not overwrite output of the original tape.
733
+ if srcCmd .Type == token .SOURCE ||
734
+ srcCmd .Type == token .OUTPUT {
735
+ continue
736
+ }
737
+ srcCmd .Source = cmd .Args
738
+ filtered = append (filtered , srcCmd )
739
+ }
740
+
729
741
p .nextToken ()
730
- return cmd
742
+ return filtered
731
743
}
732
744
733
745
// parseScreenshot parses screenshot command.
0 commit comments