Partial tq interpreter In this task you are expected to provide a list output given an input tq program. The tq programs will not contain whitespace inside them.

What is tq, in the first place?

tq is a lazy-evaluated language that is designed with the idea that array items should be accessable during the definition of them. In tq, there is no explicit separator of an array, only special arrangements of monadic/dyadic functions and nilads.

The following program is a program printing [123] (Pretend that tq doesn't support strings because we aren't dealing with them in this case):

123


This defines a list with the first item being the number 123, after which all items in the list will be outputted inside a list.

In tq, numbers are supported to allow multiple-digits. So this defines a list with 2 items:

12+12,5


In this test case, you are expected to output the list [24,5]. Let's explain it step by step.

12+12   # This evaluates 12 + 12 in the current item in the list, returning 24
     ,  # A separator. This separates two items when they could be potentially
        # ambiguous when they are applied without a separator.
      5 # This evaluates 5 in the current item in the list, returning 5
        # The comma is simply a no-op that doesn't require parsing.


So you think that tq is not hard at all to implement? Well, remember that tq also has a special feature of accessing the items in an array before the array is defined!

555th123


We introduce two new atoms:


t (tail) means access the last item in the list
h (head) means access the first item in the list


Therefore our list is going to yield:

[555,123,555,123]


Now take a look at this program:

555ps123


We introduce 2 more atoms:


p Yield the next item before (previous) the current position
s Yield the next item after (succeeding)the current position


This yields the list:

[555,555,123,123]


A quick reference of the tq language

Just assume that you only have two operands for the operators.


[0-9] starts a number. Numbers will only be positive integers, i.e. no decimals and negative numbers.
, This is a separator of different items when it is given that two consecutive indexes will be ambiguous with each other without a separator. In tq all of the remaining characters can act as a separator, but in this case it is a good idea to implement only , for the ease of your implementation.
+ and * These are arithmetic operators. Usually in tq, they may be applied multiple times, e.g. 1+2+3, but in your implementation, input will be provided so that this will not happen and only 1+2 will happen (there will not be applications multiple times).
t return the last item in the list. If the code is t1,2,3 it shall return [3,1,2,3].
h return the first item in the list. If the code is 1,2,3h it shall return [1,2,3,1].
p returns the item before the current item. If the code is 0,1,p,3,4 the code shall return [0,1,1,3,4].
s returns the item after the current item. If the code is 0,1,s,3,4 the code shall return [0,1,3,3,4].


Additional rules (with some examples)


You also have to implement multiple hops. E.g. 1th should yield [1,1,1]
If you know that something is going to form a loop, e.g. 1sp2, the cells that form the loop should be removed. Therefore the previous example will yield [1,2].
Out of bounds indexing will yield the closest index of the indexed item that is a number. E.g. 1,2s should yield [1,2,2]
If any possible indexing fails, you may do whatever operation you prefer.


More test cases


4p*p will yield [4,16]
1p+s2 will yield [1,3,2]
1,2,3h+t4,5,6 will yield [1,2,3,7,4,5,6]
3ppss6 will yield [3,3,3,6,6,6]
Jelly, 131 bytes

+Ø+o+2$};;1N;Ø½“spth+*”żF
ṣ”,µeþØD,Øa¤Ḥ2¦SSƝ&gt;2k)Ẏµe€⁾+*oḊ$k)µJç€LyⱮ"ƲVḢf?€€ØDAƑƇ.ị;@Ʋµṙ-+;×ɗị@ƭ/$¹L’$?¹Nị⁸¹L’$?ɗAƑ?€AƑ?F¥€`ÐLAƑƇFṖṖ


Try it online!

A full program taking a tq program string as its input and returning a list of integers. Still needs more golfing, but seems to work ok. Doesn’t use eval except for converting numbers from string to integer (which wouldn’t be an eval in most languages).