Skip to content

Commit 1ec7669

Browse files
Implements new spread instruction (#1740)
* Fixed bug in for loops * comment removed * Fix bugs in for loops and block exec * Fix bugs in for loops and block exec * Fix bugs in for loops and block exec * Implemented spread operator * spreadinstr * Fix formatting issues --------- Co-authored-by: chuckyang123 <xiangwall0926@gmail.com>
1 parent 07f1f87 commit 1ec7669

File tree

6 files changed

+55
-10
lines changed

6 files changed

+55
-10
lines changed

src/cse-machine/instrCreator.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { evaluateBinaryExpression, evaluateUnaryExpression } from '../utils/oper
2121
import * as rttc from '../utils/rttc'
2222
import * as seq from '../utils/statementSeqTransform'
2323
import { checkProgramForUndefinedVariables } from '../validator/validator'
24+
import { isSchemeLanguage } from '../alt-langs/mapper'
2425
import Closure from './closure'
2526
import {
2627
Continuation,
@@ -43,7 +44,8 @@ import {
4344
Instr,
4445
InstrType,
4546
UnOpInstr,
46-
WhileInstr
47+
WhileInstr,
48+
SpreadInstr
4749
} from './types'
4850
import {
4951
checkNumberOfArguments,
@@ -81,7 +83,6 @@ import {
8183
} from './utils'
8284
import { isApply, isEval, schemeEval } from './scheme-macros'
8385
import { Transformer } from './patterns'
84-
import { isSchemeLanguage } from '../alt-langs/mapper'
8586
import { flattenList, isList } from './macro-utils'
8687

8788
type CmdEvaluator = (
@@ -758,6 +759,12 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
758759
}
759760
},
760761

762+
SpreadElement: function (command: es.SpreadElement, context: Context, control: Control) {
763+
const arr = command.argument as es.ArrayExpression
764+
control.push(instr.spreadInstr(arr))
765+
control.push(arr)
766+
},
767+
761768
ArrayExpression: function (command: es.ArrayExpression, context: Context, control: Control) {
762769
const elems = command.elements as ContiguousArrayElements
763770
reverse(elems)
@@ -1310,5 +1317,30 @@ const cmdEvaluators: { [type: string]: CmdEvaluator } = {
13101317
}
13111318
},
13121319

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

src/cse-machine/patterns.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// and a final template (for the list to be transformed into).
66
import { List, Pair } from '../stdlib/list'
77
import { _Symbol } from '../alt-langs/scheme/scm-slang/src/stdlib/base'
8+
import { atomic_equals, is_number } from '../alt-langs/scheme/scm-slang/src/stdlib/core-math'
89
import {
910
arrayToImproperList,
1011
arrayToList,
@@ -14,7 +15,6 @@ import {
1415
isPair,
1516
isList
1617
} from './macro-utils'
17-
import { atomic_equals, is_number } from '../alt-langs/scheme/scm-slang/src/stdlib/core-math'
1818

1919
// a single pattern stored within the patterns component
2020
// may have several transformers attributed to it.

src/cse-machine/scheme-macros.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,20 @@ import { List } from '../stdlib/list'
44
import { _Symbol } from '../alt-langs/scheme/scm-slang/src/stdlib/base'
55
import { is_number, SchemeNumber } from '../alt-langs/scheme/scm-slang/src/stdlib/core-math'
66
import { Context } from '..'
7+
import { encode } from '../alt-langs/scheme/scm-slang/src'
78
import { Control, Stash } from './interpreter'
89
import { currentTransformers, getVariable, handleRuntimeError } from './utils'
910
import { Transformer, macro_transform, match } from './patterns'
1011
import {
1112
arrayToImproperList,
1213
arrayToList,
1314
flattenImproperList,
14-
isImproperList
15+
isImproperList,
16+
flattenList,
17+
isList
1518
} from './macro-utils'
1619
import { ControlItem } from './types'
17-
import { encode } from '../alt-langs/scheme/scm-slang/src'
1820
import { popInstr } from './instrCreator'
19-
import { flattenList, isList } from './macro-utils'
2021

2122
// this needs to be better but for now it's fine
2223
export type SchemeControlItems = List | _Symbol | SchemeNumber | boolean | string

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: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import * as errors from '../errors/errors'
66
import { RuntimeSourceError } from '../errors/runtimeSourceError'
77
import { Chapter, type Environment, type Node, type StatementSequence, type Value } from '../types'
88
import * as ast from '../utils/ast/astCreator'
9+
import { _Symbol } from '../alt-langs/scheme/scm-slang/src/stdlib/base'
10+
import { is_number } from '../alt-langs/scheme/scm-slang/src/stdlib/core-math'
911
import Heap from './heap'
1012
import * as instr from './instrCreator'
1113
import { Control, Transformers } from './interpreter'
@@ -22,8 +24,6 @@ import {
2224
import Closure from './closure'
2325
import { Continuation, isCallWithCurrentContinuation } from './continuations'
2426
import { isApply, isEval } from './scheme-macros'
25-
import { _Symbol } from '../alt-langs/scheme/scm-slang/src/stdlib/base'
26-
import { is_number } from '../alt-langs/scheme/scm-slang/src/stdlib/core-math'
2727

2828
/**
2929
* Typeguard for commands to check if they are scheme values.
@@ -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)