Execute CopyPasta Language

From Rosetta Code
Execute CopyPasta Language is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task

Implement a CopyPasta Language interpreter or compiler. These are the commands used by CopyPasta Language:

Command Description
Copy Copy the text of the following line to the clipboard
CopyFile Copy the text of the file cited in the following line to the clipboard or in the case where the next line is TheF*ckingCode copies the code to the clipboard
Duplicate Duplicate the text in the clipboard as many times as the following line specifies
Pasta! Display the clipboard and stop the program


11l

Translation of: Python
:start:
V source = File(:argv[1]).read()

V lines = source.split("\n")

V clipboard = ‘’

V loc = 0
L loc < lines.len
   V command = lines[loc].trim(‘ ’)

   X.try
      I (command == ‘Copy’)
         clipboard ‘’= lines[loc + 1]
      E I (command == ‘CopyFile’)
         I (lines[loc + 1] == ‘TheF*ckingCode’)
            clipboard ‘’= source
         E
            V filetext = File(lines[loc + 1]).read()
            clipboard ‘’= filetext
      E I (command == ‘Duplicate’)
         clipboard ‘’= clipboard * ((Int(lines[loc + 1])) - 1)
      E I (command == ‘Pasta!’)
         print(clipboard)
         L.break
      E
         exit(‘unknown command '’command‘' encountered on line ’(loc + 1))
   X.catch
      exit(‘error while executing command '’command‘' on line ’(loc + 1))

   loc += 2

C++

Translation of: Nanoquery
#include <fstream>
#include <iostream>
#include <sstream>
#include <streambuf>
#include <string>

#include <stdlib.h>

using namespace std;

// a function to handle fatal errors
void fatal_error(string errtext, char *argv[])
{
	cout << "%" << errtext << endl;
	cout << "usage: " << argv[0] << " [filename.cp]" << endl;
	exit(1);
}

// functions to trim strings 
// (http://www.martinbroadhurst.com/how-to-trim-a-stdstring.html)
string& ltrim(string& str, const string& chars = "\t\n\v\f\r ")
{
	str.erase(0, str.find_first_not_of(chars));
	return str;
}
string& rtrim(string& str, const string& chars = "\t\n\v\f\r ")
{
	str.erase(str.find_last_not_of(chars) + 1);
	return str;
}
string& trim(string& str, const string& chars = "\t\n\v\f\r ")
{
	return ltrim(rtrim(str, chars), chars);
}

int main(int argc, char *argv[])
{
	// get a filename from the command line and read the file in
	string fname = "";
	string source = "";
	try
	{
		fname = argv[1];
		ifstream t(fname);

		t.seekg(0, ios::end);
		source.reserve(t.tellg());
		t.seekg(0, ios::beg);

		source.assign((istreambuf_iterator<char>(t)), istreambuf_iterator<char>());
	}
	catch(const exception& e)
	{
		fatal_error("error while trying to read from specified file", argv);
	}

	// a variable to represent the 'clipboard'
	string clipboard = "";

	// loop over the lines that were read
	int loc = 0;
	string remaining = source;
	string line = "";
	string command = "";
	stringstream ss;
	while(remaining.find("\n") != string::npos)
	{
		// check which command is on this line
		line = remaining.substr(0, remaining.find("\n"));
		command = trim(line);
		remaining = remaining.substr(remaining.find("\n") + 1);
		
		try
		{
			if(line == "Copy")
			{
				line = remaining.substr(0, remaining.find("\n"));
				remaining = remaining.substr(remaining.find("\n") + 1);
				clipboard += line;
			}
			else if(line == "CopyFile")
			{
				line = remaining.substr(0, remaining.find("\n"));
				remaining = remaining.substr(remaining.find("\n") + 1);
				if(line == "TheF*ckingCode")
					clipboard += source;
				else
				{
					string filetext = "";
					ifstream t(line);

					t.seekg(0, ios::end);
					filetext.reserve(t.tellg());
					t.seekg(0, ios::beg);

					filetext.assign((istreambuf_iterator<char>(t)), istreambuf_iterator<char>());
					clipboard += filetext;
				}
			}
			else if(line == "Duplicate")
			{
				line = remaining.substr(0, remaining.find("\n"));
				remaining = remaining.substr(remaining.find("\n") + 1);
				int amount = stoi(line);
				string origClipboard = clipboard;
				for(int i = 0; i < amount - 1; i++) {
					clipboard += origClipboard;
				}
			}
			else if(line == "Pasta!")
			{
				cout << clipboard << endl;
				return 0;
			}
			else
			{
				ss << (loc + 1);
				fatal_error("unknown command '" + command + "' encounter on line " + ss.str(), argv);
			}
		}
		catch(const exception& e)
		{
			ss << (loc + 1);
			fatal_error("error while executing command '" + command + "' on line " + ss.str(), argv);
		}

		// increment past the command and the next line
		loc += 2;
	}

	// return in case we never hit a 'Pasta!' statement
	return 0;
}

The following files were used for testing:
prog1.cp

Copy
Rosetta Code
Duplicate
2
Pasta!

prog2.cp

CopyFile
pasta.txt
Duplicate
1
Pasta!

prog3.cp

Copy
Invalid
  Duplicate
1

Goto
3
Pasta!

prog4.cp

CopyFile
TheF*ckingCode
Duplicate
2
Pasta!

pasta.txt

I'm the pasta.txt file.
Output:
$ ./copypasta prog1.cp
Rosetta CodeRosetta Code
$ ./copypasta prog2.cp
I'm the pasta.txt file.

$ ./copypasta prog3.cp
%unknown command '' encountered on line 5
usage: ./copypasta [filename.cp]
$ ./copypasta prog4.cp
CopyFile
TheF*ckingCode
Duplicate
2
Pasta!
CopyFile
TheF*ckingCode
Duplicate
2
Pasta!

$ ./copypasta doesntexist.cp
%error while trying to read from specified file
usage: ./copypasta [filename.cp]

Go


Here's my tentative attempt at an interpreter for CopyPasta.

I've made the following assumptions:

1. The program to be interpreted is read in from a file whose path is supplied as a command line argument.

2. Writing to the clipboard should always overwrite what (if anything) is already in the clipboard and not append to it.

3. CopyPasta is case sensitive.

4. When writing commands, leading and trailing whitespace should be ignored.

5. Blank commands should be ignored.

6. When a command consumes the following line, that line should not be reprocessed if it is a command itself.

7. The program should terminate with a suitable message if any error is encountered (i.e. no following line, file doesn't exist etc.).

8. When the program is about to end and the contents of the clipboard have (when appropriate) been printed out, the clipboard should be cleared.

// copypasta.go
package main

import (
    "fmt"
    "github.com/atotto/clipboard"
    "io/ioutil"
    "log"
    "os"
    "runtime"
    "strconv"
    "strings"
)

func check(err error) {
    if err != nil {
        clipboard.WriteAll("") // clear clipboard
        log.Fatal(err)
    }
}

func interpret(source string) {
    source2 := source
    if runtime.GOOS == "windows" {
        source2 = strings.ReplaceAll(source, "\r\n", "\n")
    }
    lines := strings.Split(source2, "\n")
    le := len(lines)
    for i := 0; i < le; i++ {
        lines[i] = strings.TrimSpace(lines[i]) // ignore leading & trailing whitespace
        switch lines[i] {
        case "Copy":
            if i == le-1 {
                log.Fatal("There are no lines after the Copy command.")
            }
            i++
            err := clipboard.WriteAll(lines[i])
            check(err)
        case "CopyFile":
            if i == le-1 {
                log.Fatal("There are no lines after the CopyFile command.")
            }
            i++
            if lines[i] == "TheF*ckingCode" {
                err := clipboard.WriteAll(source)
                check(err)                
            } else {
                bytes, err := ioutil.ReadFile(lines[i])
                check(err)
                err = clipboard.WriteAll(string(bytes))
                check(err)                
            }
        case "Duplicate":
            if i == le-1 {
                log.Fatal("There are no lines after the Duplicate command.")
            }
            i++
            times, err := strconv.Atoi(lines[i])
            check(err)
            if times < 0 {
                log.Fatal("Can't duplicate text a negative number of times.")
            }
            text, err := clipboard.ReadAll()
            check(err)
            err = clipboard.WriteAll(strings.Repeat(text, times+1))
            check(err)
        case "Pasta!":
            text, err := clipboard.ReadAll()
            check(err)
            fmt.Println(text)
            return
        default:
            if lines[i] == "" {
                continue // ignore blank lines
            }
            log.Fatal("Unknown command, " + lines[i])
        }
    }
}

func main() {
    if len(os.Args) != 2 {
        log.Fatal("There should be exactly one command line argument, the CopyPasta file path.")
    }
    bytes, err := ioutil.ReadFile(os.Args[1])
    check(err)
    interpret(string(bytes))
    err = clipboard.WriteAll("") // clear clipboard
    check(err)
}
Output:

The following files have been used for testing:

// prog.cp
Copy
Rosetta Code
Duplicate
2
Pasta!

// prog2.cp
CopyFile
pasta.txt
Duplicate
1
Pasta!

// prog3.txt
Copy
Invalid
  Duplicate
1

Goto
3
Pasta!

// pasta.txt
I'm the pasta.txt file.

With the following results:

$ go build copypasta.go
$ ./copypasta
There should be exactly one command line argument, the CopyPasta file path.

$ ./copypasta prog4.cp
open prog4.cp: no such file or directory

$ ./copypasta prog.cp
Rosetta CodeRosetta CodeRosetta Code

$ ./copypasta prog2.cp
I'm the pasta.txt file.
I'm the pasta.txt file.

$ ./copypasta prog3.cp
Unknown command, Goto

Java

Translation of: Nanoquery
import java.io.File;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;

public class Copypasta
{
	// a function to handle fatal errors
	public static void fatal_error(String errtext)
	{
		StackTraceElement[] stack = Thread.currentThread().getStackTrace();
		StackTraceElement main = stack[stack.length - 1];
		String mainClass = main.getClassName();
		System.out.println("%" + errtext);
		System.out.println("usage: " + mainClass + " [filename.cp]");
		System.exit(1);
	}
	public static void main(String[] args)
	{
		// get a filename from the command line and read the file in
		String fname = null;
		String source = null;
		try
		{
			fname = args[0];
			source = new String(Files.readAllBytes(new File(fname).toPath()));
		}
		catch(Exception e)
		{
			fatal_error("error while trying to read from specified file");
		}

		// convert the source to lines of code
		ArrayList<String> lines = new ArrayList<String>(Arrays.asList(source.split("\n")));
		
		// a variable to represent the 'clipboard'
		String clipboard = "";
		
		// loop over the lines that were read
		int loc = 0;
		while(loc < lines.size())
		{
			// check which command is on this line
			String command = lines.get(loc).trim();

			try
			{
				if(command.equals("Copy"))
					clipboard += lines.get(loc + 1);
				else if(command.equals("CopyFile"))
				{
					if(lines.get(loc + 1).equals("TheF*ckingCode"))
						clipboard += source;
					else
					{
						String filetext = new String(Files.readAllBytes(new File(lines.get(loc + 1)).toPath()));
						clipboard += filetext;
					}
				}
				else if(command.equals("Duplicate"))
				{
					String origClipboard = clipboard;

					int amount = Integer.parseInt(lines.get(loc + 1)) - 1;
					for(int i = 0; i < amount; i++)
						clipboard += origClipboard;
				}
				else if(command.equals("Pasta!"))
				{
					System.out.println(clipboard);
					System.exit(0);
				}
				else
					fatal_error("unknown command '" + command + "' encountered on line " + new Integer(loc + 1).toString());
			}
			catch(Exception e)
			{
				fatal_error("error while executing command '" + command + "' on line " + new Integer(loc + 1).toString());
			}

			// increment past the command and the next line
			loc += 2;
		}
	}
}

The following files were used for testing:
prog1.cp

Copy
Rosetta Code
Duplicate
2
Pasta!

prog2.cp

CopyFile
pasta.txt
Duplicate
1
Pasta!

prog3.cp

Copy
Invalid
  Duplicate
1

Goto
3
Pasta!

prog4.cp

CopyFile
TheF*ckingCode
Duplicate
2
Pasta!

pasta.txt

I'm the pasta.txt file.
Output:
$ java Copypasta prog1.cp
Rosetta CodeRosetta Code
$ java Copypasta prog2.cp
I'm the pasta.txt file.

$ java Copypasta prog3.cp
%unknown command '' encountered on line 5
usage: Copypasta [filename.cp]
$ java Copypasta prog4.cp
CopyFile
TheF*ckingCode
Duplicate
2
Pasta!
CopyFile
TheF*ckingCode
Duplicate
2
Pasta!

$ java Copypasta doesntexist.cp
%error while trying to read from specified file
usage: Copypasta [filename.cp]

Julia

function interpretCopyPasta()
    clipboard = String[]

    if isempty(ARGS)
        println("Usage: interpretcopypasta <filename>")
        exit(1)
    end

    thecode = read(ARGS[1], String)
    codelines = String.(strip.(split(thecode, "\n")))
    nextline() = popfirst!(codelines)
    
    Copy() = push!(clipboard, nextline())

    function CopyFile()
        txt = nextline()
        push!(clipboard, txt == "TheF*ckingCode" ? thecode : read(txt, String))
    end

    function Duplicate()
        ncopies, txt = parse(Int, nextline()), copy(clipboard)
        clipboard = foldl(vcat, [txt for _ in 1:ncopies])
    end

    Pasta!() = (for t in clipboard, x in split(t, "\n") println(x) end; exit(0))
    
    commands = Dict("Copy" => Copy, "CopyFile" => CopyFile, 
        "Duplicate" => Duplicate, "Pasta!" => Pasta!)

    while !isempty(codelines)
        line = nextline()
        if haskey(commands, line)
            commands[line]()
        end
    end
end

interpretCopyPasta()
Output:

If run on the following CopyPasta "code" file:

Copy
Beginning this run.
CopyFile
TheF*ckingCode
Duplicate
2
Copy
Ending this run.
Pasta!

The output is:

Beginning this run.
Copy
Beginning this run.
CopyFile
TheF*ckingCode
Duplicate
2
Copy
Ending this run.
Pasta!

Beginning this run.
Copy
Beginning this run.
CopyFile
TheF*ckingCode
Duplicate
2
Copy
Ending this run.
Pasta!

Ending this run.

Nanoquery

// a function to handle fatal errors
def fatal_error(errtext)
	println "%" + errtext
	println "usage: " + args[1] + " [filename.cp]"
	exit(1)
end
 
// get a filename from the command line and read the file in
fname = null
source = null
try
	fname = args[2]
	source = new(Nanoquery.IO.File, fname).readAll()
catch
	fatal_error("error while trying to read from specified file")
end
 
// convert the source to lines of code
lines = split(source, "\n")
 
// a variable to represent the 'clipboard'
clipboard = ""
 
// loop over the lines that were read
loc = 0
while (loc < len(lines))
	// check which command is on this line
	command = trim(lines[loc])
 
	try
		if (command = "Copy")
			clipboard += lines[loc + 1]
		else if (command = "CopyFile")
			if (lines[loc + 1] = "TheF*ckingCode")
				clipboard += source
			else
				filetext = new(Nanoquery.IO.File, lines[loc + 1]).readAll()
				clipboard += filetext
			end
		else if (command = "Duplicate")
			clipboard += clipboard * ((int(lines[loc + 1])) - 1)
		else if (command = "Pasta!")
			println clipboard
			exit
		else
			fatal_error("unknown command '" + command + "' encountered on line " + (loc + 1))
		end
	catch
		fatal_error("error while executing command '" + command + "' on line " + (loc + 1))
	end
 
	// increment past the command and the next line
	loc += 2
end

The following files were used for testing:
prog1.cp

Copy
Rosetta Code
Duplicate
2
Pasta!

prog2.cp

CopyFile
pasta.txt
Duplicate
1
Pasta!

prog3.cp

Copy
Invalid
  Duplicate
1

Goto
3
Pasta!

prog4.cp

CopyFile
TheF*ckingCode
Duplicate
2
Pasta!

pasta.txt

I'm the pasta.txt file.
Output:
$ java -jar ../nanoquery-2.3_1845.jar -b copypasta.nq prog1.cp
Rosetta CodeRosetta Code
$ java -jar ../nanoquery-2.3_1845.jar -b copypasta.nq prog2.cp
I'm the pasta.txt file.

$ java -jar ../nanoquery-2.3_1845.jar -b copypasta.nq prog3.cp
%unknown command '' encountered on line 5
usage: copypasta.nq [filename.cp]
$ java -jar ../nanoquery-2.3_1845.jar -b copypasta.nq prog4.cp
CopyFile
TheF*ckingCode
Duplicate
2
Pasta!
CopyFile
TheF*ckingCode
Duplicate
2
Pasta!

$ java -jar ../nanoquery-2.3_1845.jar -b copypasta.nq doesntexist.cp
%error while trying to read from specified file
usage: copypasta.nq [filename.cp]

Nim

import os, strutils

type CopyPastaError = object of CatchableError

template raiseError(message: string, linenum = 0) =
  let prefix = if linenum != 0: "Line $1: ".format(linenum) else: ""
  raise newException(CopyPastaError, prefix & message)


proc copyPasta() =
  ## Load and execute a program.

  var clipboard: string

  if paramCount() != 1:
      echo "usage: ", getAppFilename().lastPathPart, " filename.cp"
      quit QuitFailure

  let path = paramStr(1)
  let code = try: path.readFile()
             except IOError: raiseError("Unable to read file “$1”.".format(path))

  let lines = code.splitLines()

  var linenum = 1   # Starting at index one for line number.
  while linenum <= lines.len:
    let command = lines[linenum - 1].strip()
    case command

    of "Copy":
      if linenum == lines.len: raiseError("missing string to copy.", linenum)
      clipboard.add lines[linenum]

    of "CopyFile":
      if linenum == lines.len: raiseError("missing file to copy from.", linenum)
      let fpath = lines[linenum]
      if fpath == "TheF*ckingCode":
        clipboard.add code
      else:
        let text = try: fpath.readFile()
                   except IOError: raiseError("unable to read file “$1”.".format(fpath), linenum)
        clipboard.add text

    of "Duplicate":
      if linenum == lines.len: raiseError("missing number of repetitions.", linenum)
      let n = try: lines[linenum].parseInt()
              except: raiseError("wrong number of repetitions.", linenum + 1)
      clipboard.add repeat(clipboard, n)

    of "Pasta!":
      stdout.write clipboard
      break

    of "":  # Empty mine: skip.
      inc linenum
      continue

    else:
      raiseError("unknown command “$1”.".format(command), linenum)

    inc linenum, 2

try:
  copyPasta()
except CopyPastaError:
  quit getCurrentExceptionMsg(), QuitFailure
Output:

File “prog1.cp”:

Copy
Rosetta Code
Duplicate
2
Pasta!

Result:

Rosetta CodeRosetta CodeRosetta Code

File “prog2.cp”:

CopyFile
pasta.txt
Duplicate
1
Pasta!

Result:

I'm the pasta.txt file.
I'm the pasta.txt file.

File “prog3.cp”:

Copy
Invalid
  Duplicate
1

Goto
3
Pasta!

Result:

Line 6: unknown command “Goto”.

File “prog4.cp”:

CopyFile
TheF*ckingCode
Pasta!

Result:

CopyFile
TheF*ckingCode
Pasta!

File “prog5.cp”:

Copy
Rosetta code
Duplicate
A
Pasta!

Result:

Line 4: wrong number of repetitions.

Perl

use strict;
use warnings;
use feature 'say';
use Path::Tiny;

sub CopyPasta {
    my($code) = @_;
    my @code = split /\n/, $code =~ s/\s*\n+\s*/\n/gr;
    return "Program never ends!" unless grep { $_ eq 'Pasta!' } @code;

    my @cb;
    my $PC = 0;
    while (1) {
        if    ($code[$PC] eq 'Copy')      {        push @cb, $code[++$PC] }
        elsif ($code[$PC] eq 'CopyFile')  { $PC++; push @cb, join ' ', $code[$PC] eq 'TheF*ckingCode' ? @code : path($code[$PC])->slurp }
        elsif ($code[$PC] eq 'Duplicate') {             @cb = (@cb) x $code[++$PC] }
        elsif ($code[$PC] eq 'Pasta!')    { return @cb }
        else                              { return "Does not compute: $code[$PC]" }
        $PC++;
    }
}

path('pasta.txt')->spew( "I'm the pasta.txt file.");

for my $prog (
    "Copy \nRosetta Code\n\tDuplicate\n2\n\nPasta!\nLa Vista",
    "CopyFile\npasta.txt\nDuplicate\n1\nPasta!",
    "Copy\nInvalid\n Duplicate\n1\n\nGoto\n3\nPasta!",
    "CopyFile\nTheF*ckingCode\nDuplicate\n2\nPasta!",
    "Copy\nRosetta Code\nDuplicate\n2\n\nPasta"
) {
    say for CopyPasta($prog);
    say '';
}

unlink 'pasta.txt';
Output:
Rosetta Code
Rosetta Code

I'm the pasta.txt file.

Does not compute: Goto

CopyFile TheF*ckingCode Duplicate 2 Pasta!
CopyFile TheF*ckingCode Duplicate 2 Pasta!

Program never ends!

Phix

Fakes four files so it can be run w/o any fiddly setup, but will handle (differently-named!) real files as well.
If run without command-line parameters it fakes four runs.
Assumes if clipboard is "hello ", Duplicate 2 should leave it as "hello hello hello ".

with javascript_semantics
constant prog1_cp = """
Copy
Rosetta Code
Duplicate
2
Pasta!
La Vista
""",
        prog2_cp = """
CopyFile
pasta.txt
Duplicate
1
Pasta!
""",
        prog3_cp = """
Copy
Invalid
  Duplicate
1
 
Goto
3
Pasta!
""",
        pasta_txt = """
I'm the pasta.txt file.
""",
        fake_files = {"prog1.cp","prog2.cp","prog3.cp","pasta.txt"},
        fake_texts = { prog1_cp , prog2_cp , prog3_cp , pasta_txt }
 
function get_file_lines(string filename)
    sequence lines
    integer k = find(filename,fake_files)
    if k then
        lines = split(fake_texts[k],"\n",false)
    elsif platform()=JS
       or get_file_type(filename)!=FILETYPE_FILE then
        crash("file not found:%s",{filename})
    else
        lines = get_text(filename,GT_LF_STRIPPED)
    end if
    return lines
end function
 
procedure interpret(string filename)
    printf(1,"\ninterpret(%s):\n",{filename})
    sequence pgm = get_file_lines(filename)&{""}
    string clipboard = ""
    integer pc = 1
    while true do
        if pc>=length(pgm) then crash("No Pasta! Sucha mistaka to maka") end if
        string cmd = trim(pgm[pc]), arg = pgm[pc+1]
        switch cmd do
            case "Copy":        clipboard &= arg&"\n" 
            case "CopyFile":    clipboard &= join(iff(arg="TheF*ckingCode"?pgm:get_file_lines(arg)),"\n")
            case "Duplicate":   clipboard &= join(repeat(clipboard,to_integer(arg)),"")
            case "Pasta!":      puts(1,clipboard); return
            case "":            pc -= 1; break -- (skip blank lines [w/o arg])
            else                crash("unknown command: %s on line %d",{cmd,pc})
        end switch
        pc += 2
    end while
end procedure
 
procedure main()
    sequence cl = command_line()
    if length(cl)=2 then
        for i=1 to 4 do
            try
                interpret(sprintf("prog%d.cp",i))
            catch e
                ?e[E_USER]
            end try
        end for
    elsif length(cl)=3 then
        interpret(cl[3])
    else
        crash("usage: CopyPasta filename")
    end if
end procedure
main()
Output:
interpret(prog1.cp):
Rosetta Code
Rosetta Code
Rosetta Code

interpret(prog2.cp):
I'm the pasta.txt file.
I'm the pasta.txt file.

interpret(prog3.cp):
"crash(unknown command: Goto on line 6)"

interpret(prog4.cp):
"crash(file not found:prog4.cp)"

Python

Translation of: Nanoquery
import sys

# a function to handle fatal errors
def fatal_error(errtext):
	print("%" + errtext)
	print("usage: " + sys.argv[0] + " [filename.cp]")
	sys.exit(1)

# get a filename from the command line and read the file in
fname = None
source = None
try:
	fname = sys.argv[1]
	source = open(fname).read()
except:
	fatal_error("error while trying to read from specified file")

# convert the source to lines of code
lines = source.split("\n")

# a variable to represent the 'clipboard'
clipboard = ""

# loop over the lines that were read
loc = 0
while(loc < len(lines)):
	# check which command is on this line
	command = lines[loc].strip()

	try:
		if(command == "Copy"):
			clipboard += lines[loc + 1]
		elif(command == "CopyFile"):
			if(lines[loc + 1] == "TheF*ckingCode"):
				clipboard += source
			else:
				filetext = open(lines[loc+1]).read()
				clipboard += filetext
		elif(command == "Duplicate"):
			clipboard += clipboard * ((int(lines[loc + 1])) - 1)
		elif(command == "Pasta!"):
			print(clipboard)
			sys.exit(0)
		else:
			fatal_error("unknown command '" + command + "' encountered on line " + str(loc + 1))
	except Exception as e:
		fatal_error("error while executing command '" + command + "' on line " + str(loc + 1) + ": " + e)

	# increment past the command and the next line
	loc += 2

The following files were used for testing:
prog1.cp

Copy
Rosetta Code
Duplicate
2
Pasta!

prog2.cp

CopyFile
pasta.txt
Duplicate
1
Pasta!

prog3.cp

Copy
Invalid
  Duplicate
1

Goto
3
Pasta!

prog4.cp

CopyFile
TheF*ckingCode
Duplicate
2
Pasta!

pasta.txt

I'm the pasta.txt file.
Output:
$ python3 copypasta.py prog1.cp
Rosetta CodeRosetta Code
$ python3 copypasta.py prog2.cp
I'm the pasta.txt file.

$ python3 copypasta.py prog3.cp
%unknown command '' encountered on line 5
usage: copypasta.nq [filename.cp]
$ python3 copypasta.py prog4.cp
CopyFile
TheF*ckingCode
Duplicate
2
Pasta!
CopyFile
TheF*ckingCode
Duplicate
2
Pasta!

$ python3 copypasta.py doesntexist.cp
%error while trying to read from specified file
usage: copypasta.nq [filename.cp]

Raku

(formerly Perl 6)

sub CopyPasta ($code) {
    my @code = $code.split("\n")>>.trim.grep: *.so;
    return "Program never ends!" unless grep { $_ eq 'Pasta!' }, @code;

    my @cb;
    my $PC = 0;
    loop {
        given @code[$PC] {
            when 'Copy'      {        @cb.push: @code[++$PC] }
            when 'CopyFile'  { $PC++; @cb.push: @code[$PC] eq 'TheF*ckingCode' ?? @code !! slurp @code[$PC] }
            when 'Duplicate' {        @cb = (flat @cb) xx @code[++$PC] }
            when 'Pasta!'    { return @cb }
            default          { return "Does not compute: @code[$PC]" }
        }
        $PC++;
    }
}

spurt 'pasta.txt', "I'm the pasta.txt file.";

(say $_ for .&CopyPasta; say '')
    for
    "Copy \nRosetta Code\n\tDuplicate\n2\n\nPasta!\nLa Vista",
    "CopyFile\npasta.txt\nDuplicate\n1\nPasta!",
    "Copy\nInvalid\n Duplicate\n1\n\nGoto\n3\nPasta!",
    "CopyFile\nTheF*ckingCode\nDuplicate\n2\nPasta!",
    "Copy\nRosetta Code\nDuplicate\n2\n\nPasta";

unlink 'pasta.txt';
Output:
Rosetta Code
Rosetta Code

I'm the pasta.txt file.

Does not compute: Goto

CopyFile TheF*ckingCode Duplicate 2 Pasta!
CopyFile TheF*ckingCode Duplicate 2 Pasta!

Program never ends!

Wren

Translation of: Go
import "os" for Platform, Process
import "io" for File

var clipboard = "" // don't have access to real thing

var interpret = Fn.new { |source|
    var source2 = source
    if (Platform.isWindows) source2 = source.replace("\r\n", "\n")
    var lines = source2.split("\n")
    var le = lines.count
    var i = 0
    while (i < le) {
        lines[i] = lines[i].trim() // ignore leading & trailing whitespace
        if (lines[i] == "Copy") {
            if (i == le - 1) Fiber.abort("There are no lines after the Copy command.")
            i = i + 1
            clipboard = lines[i]
        } else if (lines[i] == "CopyFile") {
            if (i == le - 1) Fiber.abort("There are no lines after the CopyFile command.")
            i = i + 1
            if (lines[i] == "TheF*ckingCode") {
                clipboard = source
            } else {
                var s = File.read(lines[i])
                clipboard = s
            }
        } else if (lines[i] == "Duplicate") {
            if (i == le - 1) Fiber.abort("There are no lines after the Duplicate command.")
            i = i + 1
            var times = Num.fromString(lines[i])
            if (times < 0) Fiber.abort("Can't duplicate text a negative number of times.")
            var text = clipboard
            clipboard = text * (times + 1)
        } else if (lines[i] == "Pasta!") {
            var text = clipboard
            System.print(text)
            return
        } else {
            if (lines[i] == "") {
                i = i + 1
                continue  // ignore blank lines
            }
            Fiber.abort("Unknown command, %(lines[i])")
        }
        i = i + 1
    }
}

var args = Process.arguments
if (args.count != 1) {
    Fiber.abort("There should be exactly one command line argument, the CopyPasta file path.")
}
var s = File.read(args[0])
interpret.call(s)
Output:
Similar to Go entry.

zkl

var clipBoard=Data(), srcNm=vm.arglist[0];
pasta:=File(srcNm).read().howza(11);	// zkl pastaprog.cp, stripped lines
foreach line in (pasta){
   switch(line.toLower()){
      case("copy"){ clipBoard.clear(next(__lineWalker),"\n") }
      case("copyfile"){
         n:=next(__lineWalker);
	 if(n=="TheF*ckingCode") clipBoard.clear(pasta);
	 else			 clipBoard.clear(File(n).read());
      }
      case("duplicate"){ 
         n,t := next(__lineWalker,True), clipBoard.copy();
	 do(n){ t.append(clipBoard) }	// noop if n<1
	 clipBoard=t;
      }
      case("pasta!"){ print(clipBoard.text); break; }
      case(""){}
      else{ error(__lineWalker,"Unknown command: ") }
   }
}
fcn error(w,msg){
   println("%s: %d: %s%s".fmt(srcNm, w.n, msg, w.value)); 
   System.exit(1) 
}
fcn next(w,wantInt=False){
   try{
      t:=w.next();
      if(wantInt) t=t.toInt();
      return(t)
   }catch(TheEnd){ error(w,"Error: End of file: ") }
    catch{ error(w,wantInt and "Not an int: " or "Error: ") }
}

Input programs:

//////////////prog.cp:
Copy
Rosetta Code
Duplicate
2
Pasta!

//////////////prog2.cp:
CopyFile
pasta.txt
Duplicate
1
Pasta!

/////////prog3.cp:
Copy
Invalid
  Duplicate
1

Goto
3
Pasta!

//////////////pasta.txt:
I'm the pasta.txt file.
Output:
$ zkl copyPasta.zkl prog.cp
Rosetta Code
Rosetta Code
Rosetta Code

$ zkl copyPasta.zkl prog2.cp
I'm the pasta.txt file.
I'm the pasta.txt file.

$ zkl copyPasta.zkl prog3.cp
prog3.cp: 6: Unknown command: Goto