TerminalComponentBrainfk
by Tales Miranda
HTML
<div id="console" class="console">
<div id="history" class="history">
<div class="line" v-for="text, index of history" :key="index">{{text}}</div>
</div>
<div class="input-area" @keydown.Enter="commitLine">
<div class="prompt">{{prompt}}</div>
<input class="input-line" v-model="inputLine" />
</div>
</div>
CSS
.console {
background-color: #eee;
border: 1px solid #ccc;
font-family: monospace;
}
.history .line {
white-space: pre-wrap;
}
.input-area {
border-top: 3px double #ccc;
display: flex;
}
.prompt {
white-space: pre-wrap;
}
.input-line {
width: 100%;
padding: 0;
border: 0;
background-color: transparent;
font-family: monospace;
}
JavaScript
const app = new Vue({
el: '#console',
data: {
inputLine: '',
history: [],
prompt: '? ',
inputHandler: handleInput,
},
methods: {
commitLine() {
const input = this.inputLine
this.inputLine = ''
this.outputLine(input)
// here we call some handler method
this.inputHandler(input)
},
clear() {
this.history = []
},
output(text) {
text = (text || '').toString()
const lastNewLine = text.lastIndexOf('\n')
if (lastNewLine >= 0) {
this.outputLine(text.slice(0, lastNewLine))
this.prompt = text.slice(lastNewLine + 1)
} else {
this.prompt += text
}
},
outputLine(text) {
text = this.prompt + (text || '')
this.history.push(text)
this.prompt = ''
}
},
})
const state = {
cells: {
/* 0: 65,
3: 42,
17: 99,
64: 77, */
},
dataPointer: 0,
inputSink: null,
}
function handleInput(text) {
text = text || ''
if (state.inputSink) {
state.inputSink(text+'\n')
state.inputSink = null
resume()
} else if (text.match(/!c\b/)) {
app.clear()
app.output('? ')
} else if (text.match(/!s\b/)) {
printCells()
app.output('? ')
} else if (text.match(/!r\b/)) {
state.cells = {}
state.dataPointer = 0
app.output('? ')
} else {
execute(text)
}
function execute(program) {
state.program = program
state.programCounter = 0
state.inputBuffer = null
resume()
}
function resume() {
state.running = true
for (; state.programCounter < state.program.length && state.running; state.programCounter++) {
executeOp(state.program[state.programCounter])
}
if (!state.running) {
return
}
state.running = false
app.output('\n? ')
}
function executeOp(opCode) {
switch (opCode) {
case '.':
app.output(String.fromCharCode(state.cells[state.dataPointer] | 0))
break;
case ',':
if...