There's no such thing as a free lunch ...or is there?

Your challenge is to parse my lunch bill, which contains the base price, tips, discounts, coupons, and extras and find out if my lunch was $0 or less. If this is the input:

12.34
15 tip
25 discount
1.5 extra
2 coupon


Then the output might be false. Here's how it works:

12.34 is the base price.

15 tip means to add 15% to the total.

25 discount means to subtract 25% from the total.

1.5 extra means to add 1.5 to the total.

2 coupon means to subtract 2 from the total.

There may be any amount of tips, discounts, coupons, and extras, but there will always be one base price.

Then we do (12.34 * 1.15) * 0.75 + 1.5 - 2 for an output of 10.14. 10.14 is greater than 0, so we output false. My lunch was not free.

Rules

number tip means to add number percent to the total.

number discount means to subtract number percent from the total

number extra means to add number to the total

number coupon means to subtract number from the total

Another example:

10
20 tip
20 discount
2 coupon
2 coupon
1 coupon
50 discount
2.55 coupon


The price is -0.24 ((10 * 1.20 * 0.80 - 2 - 2 - 1) * 0.5 - 2.55), so the output is true (my lunch was free.)

Notes:


Precision must be at least 2 decimal places.
You can take input as a string with newlines (trailing newline optional) or another separation character, or an array/list of the inputs.
JavaScript (ES6), 88 85 bytes

Takes input as an array of strings. Returns 0 for not free or 1 for free.

a=&gt;a.map(s=&gt;([a,b]=s.split` `,t+={e:+a,c:-a,t:x=t*a/100,d:-x}[(b||'e')[0]]),t=0)|t&lt;=0


How it works

Each line is split on the space to get a = amount, b = type of operation. If there's no operation at all (which is the case on the first line), b is set by default to "e" for "extra".

To add the correct amount to the total t, we use an object whose keys are the first letter of the operation:

{
  e: +a,           // extra
  c: -a,           // coupon
  t: t * a / 100,  // tip
  d: -t * a / 100  // discount
}


Note: If the bill consisted of only one element, map() would return a single-element array which would be coerced to an integer when applied the | operator, making the final test fail. But the OP confirmed that this can't happen. (Arrays of 2 or more elements are coerced to 0.)

Demo



let f =

a=&gt;a.map(s=&gt;([a,b]=s.split` `,t+={e:+a,c:-a,t:x=t*a/100,d:-x}[(b||'e')[0]]),t=0)|t&lt;=0

console.log(f([
'12.34',
'15 tip',
'25 discount',
'1.5 extra',
'2 coupon'
]))

console.log(f([
'10',
'20 tip',
'20 discount',
'2 coupon',
'2 coupon',
'1 coupon',
'50 discount',
'2.55 coupon'
]))