[Question]
  [
Python's [pickle module](https://docs.python.org/2/library/pickle.html) is used for serialisation, allowing one to dump an object in a way such that it can be later reconstructed. For this, pickle uses a simple stack-based language.
To keep things simple, we will be dealing with a small subset of this language:
```
(              Push a mark to the stack
S'abc'\n       Push a string to the stack (here with contents 'abc')
l              Pop everything up to the last mark, wrapping all but the mark in a list
t              Pop everything up to the last mark, wrapping all but the mark in a tuple
.              Terminate the virtual machine
```
Your task is to implement this subset of the language. Note that `\n` is a literal newline here, and newlines are actually important to the language.
For those familiar with GolfScript or CJam-like languages, `(` and `l/t` operate similarly to `[` and `]` respectively.
# Input
To keep things simple, the input will always be valid. In particular, you may assume the following about the input:
* Strings will only consist of lowercase letters and spaces `[a-z ]`, and will always use single quotes.
* There will be no extraneous characters, with all instructions being as specified above. For example, this means that newlines will only ever occur after strings.
* Every `l/t` has a matching `(` before it and every `(` has a matching `l/t` after it. There will also be at least one `(`.
* There will be exactly one `.`, and it will always be the final character.
You may take input via command line, STDIN or function argument. You may use a single newline-escaped string instead of a multiline string if you wish, but please specify this in your answer.
# Output
Output should be a representation of the final object, printed to STDOUT or returned **as a string**. Specifically:
* Strings are represented by opening and closing single quotes with content in between, e.g. `S'abc' -> 'abc'`. You may not use double quotes for this challenge, even though they are allowed in Python.
* Lists are represented by comma-separated elements surrounded by `[]` (e.g. `['a','b','c']`), while tuples are repsented by comma-separated elements surrounded by `()` (e.g. `('a','b','c')`).
* Spaces don't matter, e.g. `('a', 'b', 'c' )` is okay.
* **You cannot have a comma before the closing bracket.** Note that this is intentionally different from Python syntax rules to make things easier for most languages, and also to make it harder to simply build the list/tuple in Python then output it, due to how the single-element tuple is represented (for this challenge, we need `('a')` as opposed to `('a',)`).
## Examples
The above text might seem daunting, but the following examples should make things a bit clearer.
```
(l.
```
**Possible output:** `[]`
```
(t.
```
**Possible output:** `()`
```
(S'hello world'
l.
```
**Possible output:** `['hello world']`
```
(S'string one'
S'string two'
S'string three'
t.
```
**Possible output:** `('string one', 'string two', 'string three')`
```
(S'a'
(S'b'
S'c'
lt.
```
**Possible output:** `('a',['b','c'])`
```
((S'a'
S'b'
(lS'c'
t(S'd'
tl.
```
**Possible output:** `[('a', 'b', [], 'c'), ('d')]`
```
((S'a'
((S'b'
t(S'c'
lS'd'
(((ltlS'e'
S'f'
lS'g'
tl.
```
**Possible output:** `[('a',[('b'),['c'],'d',[([])],'e','f'],'g')]`
# Rules
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the code in the fewest bytes wins.
* Any functionality that is designed to work with Python pickles is not allowed.
---
Security note: In real code, only unpickle from sources you trust, or else you might get a nasty `cos\nsystem\n(S'rm -rf'\ntR.` surprise
  
[Answer]
# CJam, 63
```
q{"Slt 1:T;L ]',*'[\+']+ ]',*'(\+')+ [
 0:T; C+"35/T=S/(C#=~}fC
```
[Try it online](http://cjam.aditsu.net/#code=q%7B%22Slt%201%3AT%3BL%20%5D'%2C*'%5B%5C%2B'%5D%2B%20%5D'%2C*'(%5C%2B')%2B%20%5B%0A%200%3AT%3B%20C%2B%2235%2FT%3DS%2F(C%23%3D~%7DfC&input=((S'a'%0A((S'b'%0At(S'c'%0AlS'd'%0A(((ltlS'e'%0AS'f'%0AlS'g'%0Atl.)
**Explanation:**
```
q        read the input
{…}fC    for each character C in the input
  "…"    push that long string, containing code to handle various cases
  35/    split it into (two) parts of length 35
  T=     get the T'th part; T is 1 when parsing a string and 0 otherwise
          (T is initially 0 by default)
  S/     split by space into an array of strings
  (      take out the first item (containing special characters to check)
  C#     find the index of C in that string
  =      get the corresponding string from the array
          (when C is not found, # returns -1 which gets the last array item)
  ~      execute that string
```
Now the long string with various pieces of code. Each part has a few characters to check and then a block for handling each one, and the default case.
First part: `Slt 1:T;L ]',*'[\+']+ ]',*'(\+')+ [`
```
Slt      special characters to check
######## first block, corresponding to character 'S'
1:T;     set T=1, causing the next characters to be processed with the 2nd part
L        push an empty string/array, which will be used to collect the string
######## second block, corresponding to character 'l'
]        end array
',*      join with commas
'[\+     prepend a '['
']+      append a ']'
######## third block, corresponding to character 't'
]        end array
',*      join with commas
'(\+     prepend a '('
')+      append a ')'
######## last block, corresponding to other characters (practically, '(' and '.')
[        start array
```
Second part: `(newline) 0:T; C+`
```
newline  special characters to check (only one)
######## first block, corresponding to newline
0:T;     set T=0, switching back to the first part
######## last block, corresponding to any other character (including apostrophe)
C+       append the character to the collecting string
```
[Answer]
# Perl, 149 bytes
I have a bad feeling that this is a poor attempt, but here goes:
```
$/=$,;$"=",";@s=[];/^\(/?$s[@s]=[]:{$p=/S(.*')/?$1:/l|t/?($l="@{pop@s}")|/l/?"[$l]":"($l)":0,push@{$s[-1]},$p}for<>=~/([(lt]|S.*?\n)/g;print$s[0][0];
```
The script has to be saved in a file and it takes input from STDIN.
Explanation:
```
# Set the input record separator to undef so that <> reads all lines at
# once
$/=$,;
# Ensure that elements of lists printed in quotes are separated by commas
$"=",";
# The stack. Initialise the bottom element with an empty array
@s=[];
# Tokens are extracted in the for loop a few lines below. Copied here for
# clarity: Read the entire input and iterate over all valid tokens of the
# pickle language
# for <>=~/([(lt]|S.*?\n)/g;
# the token is a mark - push an empty array to the stack
/^\(/ ? $s[@s]=[]
      # token is a string, push it inside the stack top
      : {$p=/S(.*')/ ? $1
                     # otherwise, remove the top and create list or tuple
                     # from it and push it inside the top element
                     : /l|t/ ? ($l="@{pop@s}") | /l/ ? "[$l]"
                                                     : "($l)"
                             : 0 # dummy value
                             # pushing of the string/list/tuple actually
                             # happens here
                             , push@{$s[-1]},$p} 
# read the entire input at once and iterate over all valid tokens
for <>=~/([(lt]|S.*?\n)/g;
# in the end, the bottom element of the stack will be an array with just one
# element which is the string representation of the object
print$s[0][0];
```
[Answer]
# ><>, 88 bytes
```
^"][">}r]
~rl?!;o11.
^0\!\
 &</\?[1&~?=1l","
 1/\ii:"'"=?v44.
>i9%0$.     >r]i~
 ")("\
```
Fun with jumps! Uses the fact that the ASCII codes for the 5 main commands involved, mod 9, are:
```
S -> 2
l -> 0
t -> 8
( -> 4
. -> 1
```
This allows each operation to be handled on its own line, which will be jumped to directly. Also uses the stack of stacks to construct each string and nested list/tuple separately before wrapping them in the required characters.
[Answer]
# JavaScript (ES6), 199 bytes
```
s=>(q=x=>(o=[],x.slice(0,-1).map(v=>o=[...o,v.map?q(v):`'${v}'`]),x.pop()<"m"?`[${o}]`:`(${o})`),q(eval(s[r="replace"](/\(/g,"[")[r](/[tl](?![\w ]+'\n)/g,"'$&'],")[r](/S('.+')/g,"$1,").slice(0,-2))))
```
Runs several regex replaces on the input to turn it into valid JS code, then parses that.
## Test Snippet
```
f=
s=>(q=x=>(o=[],x.slice(0,-1).map(v=>o=[...o,v.map?q(v):`'${v}'`]),x.pop()<"m"?`[${o}]`:`(${o})`),q(eval(s[r="replace"](/\(/g,"[")[r](/[tl](?![\w ]*'\n)/g,"'$&'],")[r](/S('.+')/g,"$1,").slice(0,-2))))
```
```
<select oninput="I.value=this.selectedIndex?this.value.replace(/\\n/g,'\n'):'';O.innerHTML=this.selectedIndex?f(I.value):''"><option>---Tests---<option>(l.<option>(t.</option><option>(S'hello world'\nl.<option>(S'string one'\nS'string two'\nS'string three'\nt.<option>(S'a'\n(S'b'\nS'c'\nlt.<option>((S'a'\nS'b'\n(lS'c'\nt(S'd'\ntl.<option>((S'a'\n((S'b'\nt(S'c'\nlS'd'\n(((ltlS'e'\nS'f'\nlS'g'\ntl.</select><br>
<textarea rows=10 cols=20 id=I></textarea><br><button onclick="O.innerHTML=f(I.value)">Run</button><br><pre id=O></pre>
```
[Answer]
# Julia + [ParserCombinator.jl](https://github.com/andrewcooke/ParserCombinator.jl) ~~306~~ 240
With my latest set of revisions I no longer think a pure julia solution would be shorter.
```
using ParserCombinator
v=join
j(t)=v(t,",")
a=Delayed()
s=E"S'"+Star(p".")+Drop(Equal("'\n"))|>x->"'$(v(x))'"
i=Star(a)|E""
l=E"("+i+E"l"|>x->"[$(j(x))]"
t=E"("+i+E"t"|>x->"($(j(x)))"
a.matcher=s|l|t
f(x)=parse_one(x,a+E".")|>first
```
That was interesting.
I think the coded is fairly eloquent.
* Output formatting is done at generation
* `a` `l`, `i`, `t`, and `s` are basically CFG rules
* `f` is the function that is called it brings it all together.
* the `Drop(Equal("'\n"))` is annoying -- that would ideally be written as `E"\n"` but the `E` string macro does not handle escape sequences.
* Interestingly this can trivially be converted to returning julia data-structures, it is basically removing the transforms on the RHS of `|>`s and adding `tuple` for the `t` rule
]