Skip to content

Commit a1c8738

Browse files
committed
Implemented spread operator
1 parent d6fe22f commit a1c8738

File tree

4 files changed

+52
-5
lines changed

4 files changed

+52
-5
lines changed

src/cse-machine/instrCreator.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
Instr,
1717
InstrType,
1818
UnOpInstr,
19-
WhileInstr
19+
WhileInstr,
2020
} from './types'
2121
import { Transformers } from './interpreter'
2222

@@ -142,3 +142,8 @@ export const breakMarkerInstr = (srcNode: Node): Instr => ({
142142
instrType: InstrType.BREAK_MARKER,
143143
srcNode
144144
})
145+
146+
export const spreadInstr = (srcNode: Node): Instr => ({
147+
instrType: InstrType.SPREAD,
148+
srcNode
149+
})

src/cse-machine/interpreter.ts

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ import {
4343
Instr,
4444
InstrType,
4545
UnOpInstr,
46-
WhileInstr
46+
WhileInstr,
47+
SpreadInstr
48+
4749
} from './types'
4850
import {
4951
checkNumberOfArguments,
@@ -758,6 +760,13 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
758760
}
759761
},
760762

763+
764+
SpreadElement: function (command: es.SpreadElement, context: Context, control: Control) {
765+
const arr = command.argument as es.ArrayExpression
766+
control.push(instr.spreadInstr(arr))
767+
control.push(arr)
768+
},
769+
761770
ArrayExpression: function (command: es.ArrayExpression, context: Context, control: Control) {
762771
const elems = command.elements as ContiguousArrayElements
763772
reverse(elems)
@@ -1273,7 +1282,7 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
12731282
const value = stash.pop()
12741283
const index = stash.pop()
12751284
const array = stash.pop()
1276-
array[index] = value
1285+
array[index] = value;
12771286
stash.push(value)
12781287
},
12791288

@@ -1310,5 +1319,31 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
13101319
}
13111320
},
13121321

1313-
[InstrType.BREAK_MARKER]: function () {}
1322+
[InstrType.BREAK_MARKER]: function () {},
1323+
1324+
[InstrType.SPREAD]: function (
1325+
command: SpreadInstr,
1326+
context: Context,
1327+
control: Control,
1328+
stash: Stash
1329+
) {
1330+
1331+
const array = stash.pop()
1332+
1333+
// spread array
1334+
for (let i = 0; i < array.length; i++) {
1335+
stash.push(array[i])
1336+
}
1337+
1338+
// update call instr above
1339+
const cont = control.getStack()
1340+
const size = control.size()
1341+
for (let i = size - 1; i >= 0; i--) {
1342+
// guaranteed at least one call instr above
1343+
if ((cont[i] as AppInstr).instrType === InstrType.APPLICATION) {
1344+
(cont[i] as AppInstr).numOfArgs += array.length - 1;
1345+
break; // only the nearest call instruction above
1346+
}
1347+
}
1348+
}
13141349
}

src/cse-machine/types.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ export enum InstrType {
2424
CONTINUE = 'Continue',
2525
CONTINUE_MARKER = 'ContinueMarker',
2626
BREAK = 'Break',
27-
BREAK_MARKER = 'BreakMarker'
27+
BREAK_MARKER = 'BreakMarker',
28+
SPREAD = 'Spread'
2829
}
2930

3031
interface BaseInstr {
@@ -78,6 +79,10 @@ export interface ArrLitInstr extends BaseInstr {
7879
arity: number
7980
}
8081

82+
export interface SpreadInstr extends BaseInstr {
83+
symbol: es.SpreadElement
84+
}
85+
8186
export type Instr =
8287
| BaseInstr
8388
| WhileInstr
@@ -86,6 +91,7 @@ export type Instr =
8691
| BranchInstr
8792
| EnvInstr
8893
| ArrLitInstr
94+
| SpreadInstr
8995

9096
export type ControlItem = (Node | Instr | SchemeControlItems) & {
9197
isEnvDependent?: boolean

src/cse-machine/utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,7 @@ const propertySetter: PropertySetter = new Map<string, Transformer>([
940940
[InstrType.APPLICATION, setToTrue],
941941
[InstrType.ASSIGNMENT, setToTrue],
942942
[InstrType.ARRAY_LITERAL, setToTrue],
943+
[InstrType.SPREAD, setToFalse],
943944
[
944945
InstrType.WHILE,
945946
(instr: WhileInstr) => {

0 commit comments

Comments
 (0)