Skip to content

Commit a1c781a

Browse files
committed
simplify text rep
1 parent 357c351 commit a1c781a

4 files changed

Lines changed: 150 additions & 384 deletions

File tree

docs/doc-plan.md

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,19 @@ correspond to the tooltips used in MicroCode's visual editor
3131
(where the underscores are replaced by spaces), which
3232
accounts for their long form.
3333

34-
A program (PROG) consists of 5 pages, numbered P_1 to P_5, each with a (possibly
35-
empty) sequence of rules RULE:
36-
37-
PROG := P_1 RULE\* P_2 RULE\* P_3 RULE\* P_4 RULE\* P_5 RULE\*
38-
39-
So, the following program is the empty program
34+
A program consists of (at most) 5 pages, identified
35+
by `page_i:`, where 1 <= i <= 5.
36+
Each page identifier is followed by a (possibly empty)
37+
sequence of rules RULE:
4038

4139
```
42-
P_1 P_2 P_3 P_4 P_5
40+
page_i: RULE*
4341
```
4442

43+
Rules that are presented without a preceding page identifier
44+
are added to page 1. Pages need not be presented in order.
45+
Each page identifier can appear at most once.
46+
4547
Each rule has an optional section WHEN and an optional section DO.
4648

4749
RULE := when [WHEN] do [DO]
@@ -200,13 +202,13 @@ Actions have effects by writing to (updating) a resource, which are as follows:
200202
- variable Z
201203
- current page
202204

203-
If two rules have actions that target the same resource, they are said
205+
If two rules have actions that update the same resource, they are said
204206
to be in _conflict_ if it is possible for them to execute at the same time.
205207

206208
### Rule matching
207209

208210
Upon reception of a signal, it is first necessary to find the
209-
rules that are enabled for execution by the signal. The first
211+
rules that are _enabled_ for execution by the signal. The first
210212
step is to find the rules that mention the named signal. Then
211213
the optional conditions associated with those rules are evaluated
212214
in the current state (of variable and sensor values) to prune this
@@ -218,7 +220,8 @@ execution of any currently active rules that conflict with
218220
a rule in E.
219221

220222
The set E is then partition into three sets, I, S, and T, corresponding
221-
to rules whose actions execute instantly, those that switch page, and those that take time. Instant actions are
223+
to rules whose actions execute instantly, those that switch page,
224+
and those that take time. Instant actions are
222225

223226
- assignments to variables
224227
- radio send
@@ -237,3 +240,40 @@ T are started.
237240
### Switching pages
238241

239242
### Timers
243+
244+
## Example
245+
246+
Here is the MicroCode program corresponding to
247+
the [emotion badge](https://microbit.org/projects/make-it-code-it/emotion-badge/)
248+
project:
249+
250+
```
251+
when press button_A do show_image
252+
image `
253+
. . . . .
254+
. 1 . 1 1.
255+
. . . . .
256+
1 . . . 1
257+
. 1 1 1 .
258+
`
259+
260+
when press button_B do show_image
261+
image `
262+
. . . . .
263+
. 1 . 1 .
264+
. . . . .
265+
. 1 1 1 .
266+
1 . . . 1
267+
`
268+
```
269+
270+
The MakeCode program is
271+
272+
```
273+
input.onButtonPressed(Button.A, function () {
274+
basic.showIcon(IconNames.Happy)
275+
})
276+
input.onButtonPressed(Button.B, function () {
277+
basic.showIcon(IconNames.Sad)
278+
})
279+
```

interpreter.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,7 @@ namespace microcode {
7575
}
7676

7777
public start(timer = false) {
78-
if (
79-
!this.interp.running ||
80-
this.actionRunning ||
81-
this.backgroundActive
82-
)
78+
if (!this.interp.running || this.active() || this.backgroundActive)
8379
return
8480
this.reset()
8581
const time = this.getWakeTime()
@@ -152,7 +148,7 @@ namespace microcode {
152148
}
153149

154150
private ok() {
155-
return this.interp.running && this.actionRunning
151+
return this.interp.running && this.active()
156152
}
157153

158154
private timerOrSequenceRule() {
@@ -164,7 +160,7 @@ namespace microcode {
164160
// make sure we have something to do
165161
if (this.rule.actuators.length == 0) return
166162
// prevent re-entrancy
167-
if (this.actionRunning) return
163+
if (this.active()) return
168164
this.actionRunning = true
169165
control.runInBackground(() => {
170166
this.backgroundActive = true

mcparser.ts

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,16 @@ namespace microcode {
3535
)
3636
}
3737
const pageToString = (page: PageDefn) => {
38-
const res = page.rules.map(ruleToString)
38+
const res = page.rules.map(ruleToString).filter(r => r != "")
3939
return res.join("\n")
4040
}
4141
const res = prog.pages.map(pageToString)
42-
ret.s = res.map((ps, i) => `P_${i + 1}\n${ps}`).join("\n")
42+
ret.s = res
43+
.map((ps, i) =>
44+
ps == "" && i > 0 ? "" : i == 0 ? ps : `page_${i + 1}:\n${ps}`
45+
)
46+
.filter(s => s != "")
47+
.join("\n")
4348
}
4449

4550
enum Phase {
@@ -105,8 +110,9 @@ namespace microcode {
105110
const prog = new ProgramDefn()
106111
prog.pages = []
107112

108-
let nextPageNum = 1
113+
let pageMap: { [key: number]: PageDefn } = {}
109114
let currPage: PageDefn = undefined
115+
let currPageNum: number = undefined
110116
let currRule: RuleDefn = undefined
111117
let currTile: Tile = undefined
112118
let tok: string = undefined
@@ -133,22 +139,36 @@ namespace microcode {
133139
continue
134140
}
135141
currTile = undefined
136-
if (tok.indexOf("P_") == 0) {
137-
control.assert(tok.length == 3, `expected P_[1-5], got ${tok}}`)
138-
const pageNum = parseInt(tok[2])
142+
if (
143+
tok.indexOf("page_") == 0 &&
144+
tok.indexOf(":") == tok.length - 1
145+
) {
146+
control.assert(
147+
tok.length == 7,
148+
`expected page_[1-5]:, got ${tok}}`
149+
)
150+
const pageNum = parseInt(tok[5])
139151
control.assert(
140-
pageNum == nextPageNum,
141-
`expected P_${nextPageNum}, got P_${pageNum}`
152+
pageNum >= 1 && pageNum <= 5,
153+
`page number must be between 1 and 5, got ${pageNum}`
142154
)
143-
if (currPage) {
155+
if (currPage && currPageNum !== undefined) {
144156
if (currRule) currPage.rules.push(currRule)
145-
prog.pages.push(currPage)
157+
pageMap[currPageNum] = currPage
146158
currRule = undefined
147159
}
160+
assert(
161+
pageMap[pageNum] == undefined,
162+
`page ${pageNum} redefined`
163+
)
148164
currPage = new PageDefn()
149-
nextPageNum++
165+
currPageNum = pageNum
150166
} else if (tok == "when") {
151-
control.assert(currPage != undefined, `No page defined`)
167+
if (currPage == undefined) {
168+
currPage = new PageDefn()
169+
currPageNum = 1
170+
pageMap[currPageNum] = currPage
171+
}
152172
if (currRule) currPage.rules.push(currRule)
153173
currRule = new RuleDefn()
154174
phase = Phase.Sensor
@@ -163,7 +183,18 @@ namespace microcode {
163183
}
164184
}
165185
if (currRule) currPage.rules.push(currRule)
166-
prog.pages.push(currPage)
186+
if (currPageNum !== undefined) {
187+
pageMap[currPageNum] = currPage
188+
}
189+
190+
// Build pages array from 1 to 5, including only pages that were defined
191+
for (let i = 1; i <= 5; i++) {
192+
if (pageMap[i]) {
193+
prog.pages.push(pageMap[i])
194+
} else {
195+
prog.pages.push(new PageDefn())
196+
}
197+
}
167198
ret.p = prog
168199
}
169200

0 commit comments

Comments
 (0)