[Question]
  [
Sometimes in chat, if someone says something you agree with, you'll send a message with an `^`, which points at the message above:
```
Radvylf: Cats are far superior to JavaScript
You: ^
```
Sometimes you'll also add some text:
```
Radvylf: I sure do like integers
You: I mostly agree with ^ but floats are pretty neat too
```
You can also use multiple `^`s to refer to messages farther back:
```
Timmy: Puppies are adorable.
Radvylf: I hate puppies.
You: ^^
```
In this challenge, given a chat log with `^`s, you'll replace the `^`s with the messages they refer to.
**Task:**
Given a multiline string of messages (without usernames), or an array where each message is a string (or some representation of one), resolve all of the `^` references in it. Note that messages can refer to messages that themselves have `^`s, which need to be properly resolved.
For example:
```
Cats are funny sometimes
^
^^, but I've met serious cats too.
^^
Opinions on static typing?
It's okay.
^ It depends on the implementation, though.
^ Big difference between good and bad static ty
^ping
Thanks ^_^
```
This would become:
```
Cats are funny sometimes
Cats are funny sometimes
Cats are funny sometimes, but I've met serious cats too.
Cats are funny sometimes
Opinions on static typing?
It's okay.
It's okay. It depends a lot on the implementation, though.
It's okay. It depends a lot on the implementation, though. Big difference between good and bad static ty
It's okay. It depends a lot on the implementation, though. Big difference between good and bad static typing
Thanks It's okay. It depends a lot on the implementation, though. Big difference between good and bad static typing_It's okay. It depends a lot on the implementation, though. Big difference between good and bad static typing
```
You'll never need to resolve a group of `^`s that points up more times than there are messages to point at. E.g., `^` will never be the first line, and `^^` will never be the second.
**Test cases:**
Input:
```
a
```
Output:
```
a
```
Input:
```
a
^b
^^
```
Output:
```
a
ab
a
```
Input:
```
a
^b
^c
^ ^^ ^^^
```
Output:
```
a
ab
abc
abc ab a
```
**Other:**
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so shortest answer in bytes per language wins.
  
[Answer]
# JavaScript (ES6), 56 bytes
Expects and returns an array of strings.
```
a=>a.map((s,i)=>a[i]=s.replace(/\^+/g,s=>a[i-s.length]))
```
[Try it online!](https://tio.run/##jYtBDsIgEEX3nIJdh0jpCfAitSQjThGDQDqN18dWu3Rh8pOXn/f/A1/Ifol17XO5UZttQ3tG88QKwDqqrYxxsmwWqgk9wXBxpyFo/oieTaIc1vukVPMlc0lkUgkwwyik7LATmxE/jd7hrgfd30t/ULo93197Aw "JavaScript (Node.js) – Try It Online")
[Answer]
# [brainfuck](https://github.com/TryItOnline/brainfuck), 240 bytes
```
+>>,[[->+<<+>]>----------[+[-<+++>]<+[[-]<.>>,>>>>]<[[[<]<]+[[>]>]<<,[->+++>+<<]+++++[->-----<]>-[[-]<<[[<]<]>>->[.[[>]>]>[->+<]<<+[[<]<]<+>>>-[[[>]>]<<+[[<]<]<+>>>-]>]<<<<[[->>>+<<<]<]>>>+[[>]>->>]<+[-<+>]>>]>[[-]<<+>]<]]<<[.[-]>>>+>>,>]<]
```
[Try it online!](https://tio.run/##VY6xboUwDEV3vsLbG0L4gsiV2ulNXbpFoQpgIHolQSS04uupE6pW9ebrc@91t1nnx71/nKdArLWWKJQSaFD@jhZaKiFYVIIBoxomkccorbUyyrDMDqNUnf1McoYReXgvGYoDi1ddDkSJurlsWEr5JK4b12OmfzL/qUXJIZI3brmy8HpAYnlRlv9zbinMf5tc3PCa2fw9S@f5YlMEuxGMu/cHxLBQcgvFqq3atoZuT3C/fRKwDJE2F/YIffakEBpGqtfVeRd8hOAhJptcD@lgbXqq7unG8sMeDMI9wUAr@aGQaSZwy/pBC/lsCr5mLezTnNlnN8HgxpE28j1BR@mLyMMUwgDWD9DZ4a@ranNb9TZb/4jQvrff "brainfuck – Try It Online")
Now works with blank lines. This ended up saving bytes, and the slightly altered tape structure allowed the two other improvements I had tried earlier to save bytes as well.
The tape structure of this program is as follows:
```
1 firstline 0 0 0 1 secondline 0 0 0 ... 1 lastline 0 input
```
The 1 cell at the beginning of each line allows the program to cope with empty lines and lines beginning with `^` without additional effort. It also allowed me to shorten the gap between text lines, which saved a small number of bytes.
With formatting and comments:
```
Initialize tape with first line marker and input
+>>,
While there is input:
[
  Duplicate input
  [->+<<+>]
  Test for newline
  >----------
  If not newline:
  [
    Test for ^ (94)
    +[-<+++>]<+
    If anything else:
    [
      Output letter and take next input
      [-]<.>>,
      Move so rest of loop will end at next input cell
      >>>>
    ]
    If caret    
    <[
      Place 1 between text lines to track which line to copy
      [[<]<]+[[>]>]<<
      Duplicate next input and check if caret
      (there's probably a shorter way to do this)
      ,[->+++>+<<]+++++[->-----<]>-
      If not another caret:
      [
        Clear test cell
        [-]
        Move to start of line to copy and delete the 1 from it
        <<[[<]<]>>->
        For each letter in that line:
        [
          Output
          .
          Move next input cell to the right
          [[>]>]>[->+<]
          Populate cell to copy to; start backup copy too
          <<+[[<]<]<+>>>-
          Copy letter to (next letter in current line) and (backup 3 left)
          [[[>]>]<<+[[<]<]<+>>>-]
        >]
        Restore line and initial 1 cell
        <<<<[[->>>+<<<]<]>>>+
        Clear indicators between lines
        [[>]>->>]
        Move input to correct cell
        (that cell contains negative one from the previous loop)
        <+[-<+>]
      >>]
      If was another caret:
      >[
        Delete input and set indicator to repeat caret loop
        [-]<<+>
      ]
  <]]
  If newline:
  <<[
    Output newline
    .
    Set up next line
    [-]>>>+>>,>
  ]
<]
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly),~~19~~ ~~18~~ 17 bytes
```
ɓŒgċ”^ịṭʋ€Ṛ}Fṭðƒḟ
```
[Try it online!](https://tio.run/##RY2xSsRAEIb7fYrprjl8BUFBSGVjY7OyyU6SvUtmQ3bjkUJQG8F0d50gFrYKFhaGA5vTg/MtNi8SdwU5mGLm4/vnn2FRtOO4W30vs69uuH7kbt25/vWnG25fXP9wdeKPzdt26T6exuHmkzGvrlz/7Nbvm7vz7b3XZuMoGBOMx4zz/yVhHHgYT46FNSBqhLQhasHoEq0q0TDuA1OIGwvR5BLBYzBYK90YSELGan0Qfp5WipQmA5rAWGFVArb1LDtkkZ14PBetFyGyILFCkn@mzRFUWRVYIoWQpqlnusny4B6pDKRKU6yREoQY7QKRINNagiAJsZD7LsZDGzvLBc0N8Av@Cw "Jelly – Try It Online")
*-1 thanks to Jonathan Allan*
*-1 thanks to Jonathan Allan again*
Takes and returns lists of lines.
```
              ð ḟ    Starting with the input without any of its elements,
               ƒ     reduce by:
ɓ                    with reversed arguments: (line on left, lines on right)
 Œg                  Runs of consecutive equal elements.
        ʋ€           For each run:
       ṭ             append the run to
           }         the accumulated lines
          Ṛ          reversed
      ị              and get the item at the 1-index of
   ċ”^               the number of carets.
            F        Flatten the runs and substitutions back together,
             ṭ       and append to the list of accumulated lines.
```
Love when I shave two bytes off (from `ɓŒg=”^Sị⁸¹?ɗ€Ṛ}Fṭµƒ“”`) in the course of writing an explanation :P
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), 31 bytes
```
+1`(\^)+(?<=(.*)(?<-1>¶.*)+)
$2
```
[Try it online!](https://tio.run/##RY1NSsRAEIX3fYq3ECYx48C41hnQVVZuXEprJ11JmjHVIV1RcjEP4MVitSBCQT0@3s9MEthtW3V8K15sWRXnu/vicF3qvzmevr9UVqW5ut02Z4wztjHW/onWWNh8Sh6dJLiZ0C3MK1IctXikZKwG9mgWQb37IChGojnEJaHNGYnxkDufpsAhckJkJHESWsiqrD@bWnaKL25VI2qBp4nY/zplIIRxeqeROIci75XFpR@y9yH08KHraCZuCQ3JJxGjj9HDsUfj/P@WsXnNPA@OLwn21f4A "Retina 0.8.2 – Try It Online") Link includes test cases. Explanation:
```
+1`
```
Replace one match at a time, repeating until all matches have been replaced. (This allows a replaced line to be referenced in a later line.)
```
(\^)+(?<=(.*)(?<-1>¶.*)+)
```
Match a number of `^`s, then search back that many lines for the replacement text.
```
$2
```
Replace the `^`s with the found text.
[Answer]
# [Python 3](https://docs.python.org/3/), 87 bytes
```
import re
def f(a,*q):
	for x in a:q+=re.sub("\^+",lambda k:q[-len(k[0])],x),
	return q
```
[Try it online!](https://tio.run/##FY3NCoMwEITP5ikWT0lNRehN6JNYA7EmNBjzs0awT592YWBg@GYmfcsnhketbk8RC6Bhq7FguZa3LEbW2IhwgQugx9w90fTHufD2pbpWer0vq4ZtzNPdm8C3aZjFLC8hWYOmnBggV@p7FwxNWB7TnxtEj0avXPRHQZfIk3eFqIMLOk3oQuEUiKqZWph6MwWKpH4 "Python 3 – Try It Online")
-11 bytes thanks to Unrelated String
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~57~~ 51 bytes
```
->c,*q{c.map{|l|q<<l.gsub(/\^+/){|r|q[-r.size]}};q}
```
[Try it online!](https://tio.run/##KypNqvyfZvtf1y5ZR6uwOlkvN7GguianptDGJkcvvbg0SUM/Jk5bX7O6pqimMFq3SK84syo1trbWurD2f0FRZl6JQppecmJOjka0UqJSrKaCsgKYwcWFIamjFJcEIuIgysAiiSAR/MqTQYRCHAjFISyAaU1KhpAKiUkKQHP@AwA "Ruby – Try It Online")
* Saved 6 Bytes thanks to @G B
Lambda taking and returning an array of lines.
Instead of iterating the size of the array G B proposed to build the output by adding lines one by one, so that we take from that the previous (size of match) line.
We use *gsub* and the {|match| block form } which brings the last match every time.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 18 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
εD'^ÃηRāR(N+¯sè:=ˆ
```
Input as a list of lines.
[Try it online](https://tio.run/##RY0xS8RAEIX/ypAmByb@gAMR1CaNwmEnrmyyk2S5y0zITJTYieBvsbMSe89OuL8Ud2NxxbyB977HY7Glx3k@fF6lZv96@Nr8vGxW1yffH7J/X5/9vs3zXXJpVcAOCPVINIFwh@o7lCRLTDyTQTkqFOkjQohAcPA8ClSxp8ynCxTkpvfkmQSYQNSqr0Cn4DXnISw0DcHWTgsOhYLDHskttLYIvut32CHFIlMWPB6b9p@@8A04X9c4IFUIJeoTIkHD7MCSg9K642JsxNXwb1tLWwHzYJL7Oc@J8519nv4A) or [verify all test cases](https://tio.run/##XU/NSsNAEL77FMNeIrjxAQoSUC@5WCjeSiObZJosbWZDdlKJ4EEEn8WbF3/uqTehr5TuJoIgDDPM9zMfY6xKNQ47EVPd8gxE1MkTMW952mQ3HD6ug2T/fPhafD8tTm/O@je7f51d/LwMj/1n1L8Py6VQYiXBDymS1LfkP5D5BomvX@5KsQXVIKxbog6sqZB1hdYLxxMS0pYhDnYIjgKLjTathcz72JjzKUeKea1JG7JgCCwr1hlw57AicmTMgSM2qhvlEDPkWCPlo5pLBF3VW6yQvNGQdJhpi3JSX@oCcr1eY4OUIaTI94gEhTE5KMohVflfonf4VDdvS0UbC8mde3U1hCGZcKseuiM).
**Explanation:**
```
ε           # Foreach of the (implicit) input-list:
 D          #  Duplicate the current line
  '^Ã      '#  Pop the copy, and only keep its "^"
     η      #  Pop and push the list of prefixes of this "^"-string
      R     #  Reverse this list of prefixes
  ā         #  Push a list in the range [1,length] (without popping)
   R        #  Reverse it to range [length,1]
    (       #  Negate each to range [-length,-1]
     N+     #  Add the 0-based loop-index to each: range [N-length,N-1]
       ¯    #  Push the global array
        s   #  Swap so the list of indices is at the top again
         è  #  Index each into the global array
  :         #  Replace all "^"-strings with these strings in the current line
   =        #  Print the modified line with trailing newlines (without popping)
    ˆ       #  Pop and add it to the global array
```
[Answer]
# [D](https://dlang.org/), 100 bytes
Returns by modifying its input, exits with error.
```
import std;void f(string[]s){for(int i;;i++)s[i]=s[i].replaceAll!(x=>s[i-x[0].length])=`\^+`.regex;}
```
[Try it online!](https://tio.run/##RVFLb4MwDL7zK7xeCupD3Rl10zbt0NMuu3WwBmIgKjhVYvpQxW/vHDZ1UuIo/h7@lOjbzXQH6xg86/RojYYq9uwM1dvMJ9fKutgQg0lTM5slfmuydShLh4dWlfjStg/xef0kvcV5u8qWLVLNTZasd1/5bCe0Gs/pcBudXU93b2D0nMA1AmB3kaHjPYVScdlA/O6cdYBCGAJDsCWqsnk4OcPYUhoNUTR6dspQnASb7URN5pO8CKUMBfKw8omE7UUB8CeOp4tpyI@K48dVkqSj@E2xB@UQqp7oAt52yKZDH5zCzudQ9Ayb6RFBIPDojO19COyBrV2OJCkfB0PGkgdL8qiKTQl8kV79LOCGpwLs1WWkw4ZBSxDSI5sbBPmNFjukILQ0l57t6@aX/Wpq0Kaq0CGVCAXyCZGgtlaDIg2F0v8TgyJMlfOzUbT3kH/f32K4/QA "D – Try It Online")
---
# [D](https://dlang.org/), 97 bytes
This one returns a Range and doesn't error.
```
import std;
```
```
(string[]s,int i=0)=>s.map!(r=>s[i++]=r.replaceAll!(x=>s[i+~x[0].length])=`\^+`.regex)
```
[Try it online!](https://tio.run/##RZBNb4MwDIbv/RUuF0BlqDsjNm079bTLbh2sKTEQFRyUmH5o6v46S@jUSYlt2c9rW5bTpPpBGwbLMhMja6jzyLJR1GwLmyhiUPk6zp9s2othGRkXbdVqVeQmNTh0osKXrltG51v@57xdF2mH1HBbxPnus1ztHNfgOZ6yxVErCWak@wBgtBzD9wKgjuY4RVG1y5NRjB1li@viJuqFoij23DYQQRKUe28qb6D0rwyK1HXOHPEnjsKH0K@IgqPHdRxns/hNsAVhEOqR6AJW98iqR@s7@V8msB8ZNuERwZXAolF6tFB5HWudzpAz74MipcmCJnc7waoCvrhc8@yKGw5d4SAuMw4bBukWITnT3CK4o3fYI3mhpsTl9Ni0N/pVNSBVXaNBqhD2yCdEgkZrCYIk7IX8n@gVfqrzH62gg4Xy636L6/QL "D – Try It Online")
[Answer]
# [APL (Dyalog Unicode)](https://www.dyalog.com/), 43 bytes
Full program. Prompts for and prints list of strings.
```
⊢{(⍵⊃t)←'\^+'⎕R{t⊃⍨i-≢⍵.Match}t⊃⍨i←⍵}¨⍳≢t←⎕
```
[Try it online!](https://tio.run/##RY@/TsMwEId3P8VtAdFW8ARIIIYOCEQZUZAbXxOrjR3FF1BUdQLxpyiIhZWhXbpXvACP4hcJ5yBUL7Y@fb/7nWUx66tazmzaOlK2Iv/0Mffvn3z55nvxs/HLtX97ZDI6G1gzQue0NZelNsGM/jIRG/zSpgs3XyHWbIV/eS5av1zN93iUXz7QfojcxAcRj7uaEyPfbHTfv65YGJxLSrLFP90t0GxZCG2canlmC90pRFcJR4fiVJIDWSJMKmNqcDZH0jk6EYs47sG4IhhGdwiMwWGpbeUgCRmydsCKuCi04W85sAYcSdIJUM0sPRZDihhPZc0iDAkUFmhUZ1KGoPNihjmaELKmx8xWaRbcE52C0pMJlmgShDHSPaKB1FoF0igYS7XrEnFoE9eZNFMH8W38Cw "APL (Dyalog Unicode) – Try It Online")
`⎕` prompt for text from console
`t←` store in `t`
`≢` tally of texts
`⍳` **i**ndices 1 through that
`{`…`}¨` apply the following anonymous lambda to each text; argument is `⍵`:
 `i←⍵` store argument as `i`
 `t⊃⍨` pick that element from the input
 `'\^+'⎕R{`…`}` **R**eplace each run of carets with:
  `⍵.Match` the match
  `≢` the length of that
  `i-` subtract that from `i`
  `t⊃⍨` pick that element from the input
 `(⍵⊃t)←` in-place update the argument'th element of `t` with that (and implicitly return it)
`⊢` return (and implicitly print) that
[Answer]
# [SNOBOL4 (CSNOBOL4)](http://www.snobol4.org/csnobol4/), 106 bytes
```
	T =TABLE()
I	X =X + 1
	I =INPUT	:F(END)
R	I SPAN('^') . K =T[X - SIZE(K)]	:S(R)
	T[X] =OUTPUT =I	:(I)
END
```
[Try it online!](https://tio.run/##FYzBCsIwDEDPyVfktgRREDwVepisQpnUsXYwlAWcV3EH/58a4Z0evPf9bOv2PtUKhXxpz9fAghFm8jPt6IgQycc0TAXchUPqBEdTeWgTN9oIHai37jHTnnK8B@5lAZd5FASzC/nbVKy2CTiOgrao9Ym6or5QSf/oDw "SNOBOL4 (CSNOBOL4) – Try It Online")
[Answer]
# Lua, 83 bytes
```
s=...;for i,l in ipairs(s)do print((l:gsub("%^+",function(m)return s[i-#m]end)))end
```
Must be loaded as a "chunk" (file or string). Expects input as table of strings. Prints output.
[Answer]
# [C++ (gcc)](https://gcc.gnu.org/), ~~191~~ ~~186~~ 181 bytes
```
#import<regex>
int f(std::string*a,int n){for(int b=0,c,i;b<n;++b)for(i=-1;++i<a[b].size();c?a[b].replace(i-c,c,a[b-c]),i+=a[b-c].size()-c:0)for(c=0;a[b][i]==94;++c)++i;}
```
[Try it online!](https://tio.run/##TU7RaoQwEHz3K4KFXlJjuYIvZ5L2Q6xC3IuycCaiEUrFb7eJ3kOXZZgddmcHxjHvAfb9BYfRTV5Opjc/nwlaTzo6@3tZzn5C279pHjXL1s5NNNJWXTlwFK20Istadugq/wgDSl219fuMv4YyAV/HNJnxocFQzCHcBSmHmnHM1Emf2zmU18MK1FXEuwprpW5FcAUWnMUWolp4LHcj0YVsRg9n3EGjpSxZExLqX3Kiq6JeU53ytGkjQATSxG7STRz7HdW8YE8evzs7e6IX78grkpJodlqCWzyRkmCEy7e9iGRL9j8)
Dang, this is bad. Only wins the Brainfuck answer lol.
For anyone trying to help here's the ungolfed code:
```
#include <iostream>
#include <vector>
#include <string>
void chat_reference(std::vector<std::string> &chat)
{
    for(int list_message = 0; list_message < chat.size(); ++list_message)
    {
        int reference_counter = 0;
        for(int i = 0; i < chat[list_message].size(); ++i)
        {
            while(chat[list_message][i] == '^')
            {
                ++reference_counter;
                ++i;
            }
            if(reference_counter > 0)
            {
                chat[list_message].replace(i - reference_counter, reference_counter, chat[list_message - reference_counter]);
                i += chat[list_message- reference_counter].size() - reference_counter;
                reference_counter = 0;
            }
        }
    }
}
```
*-6 bytes thanks to ceilingcat*
*-4 bytes thanks to ceilingcat*
*-11 bytes thanks to ceilingcat*
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), ~~51~~ 43 bytes
```
ＷＳ«⊞υω≔⁰θＦ⪪⁺ιψ^¿κ«⊞υ⁺⁺⊟υ⎇θ§υθω⁻κψ≔±¹θ»≦⊖θ»υ
```
[Try it online!](https://tio.run/##RY89b4MwEIbn@FecssRItGrnDFU/Foa0kZKZyoEDLOBM7HNSVOW3U5uk7XKSXz3vh4tG2cKobprOje4QZEaD5x1bTbVMEvgWi613jfQpnJO1WDw7p2uSDykc47MyFuRu6DTLbeed1CmMSQrLfBm8ugLZzhF/GTN0PWaQPqB7tKTsKI8pPHNGJX5F7pjEvnA2mgLcxtgkFv4OeMdaMcrH5DbkIhbYOYSNGm7EGxYWeyTG8spcxDb8ikPreppeFTtQFqHyRCM40yPrHp3IRZ6ncPAM2eqEEGRwaLXxDoroYWPuAyI@Bk3akAND4FixLoDHoNVPIuNVkFs1BhAyhhIHpHImuUHQ/dDNw4LJUBo04@smsi@6hlJXFVqkAuGAfEYkqI0pQVEJB1X@d4k8tol9o6h1kH/mYro7dT8 "Charcoal – Try It Online") Link is to verbose version of code. Takes input as a list of newline-terminated lines. Explanation:
```
ＷＳ«
```
Repeat for each line.
```
⊞υω
```
Add a new empty output line to the predefined empty list.
```
≔⁰θ
```
Start with no `^`s.
```
Ｆ⪪⁺ιψ^
```
Append a null character to the input line, split the result on `^`s and loop over the pieces.
```
¿κ«
```
If this piece is not empty, then...
```
⊞υ⁺⁺⊟υ⎇θ§υθω⁻κψ
```
... remove the last line, concatenate a previous line if there were `^`s accumulated, concatenate the split piece without any null characters, and add it back to the list of lines (the indexing for the previous line works because the last line isn't in the array during the concatenation); then...
```
≔±¹θ
```
... set the number of `^`s to `1` assuming that there's a following piece that was separated from this piece with a `^`.
```
»≦⊖θ
```
Empty pieces correspond to consecutive `^`s so simply increment the number of `^`s.
```
»υ
```
Output the final list of lines.
]