Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
const simplePseudoOp: Parser = (function() {
// FIXME: No expressions allowed in DB statements, to make it fast to parse.
const dbConst: Parser = alt(
numberLiteral.map(n => [n]), // 8BIT but no exprs pls
stringLiteral.map(s => s.split('').map(c => c.charCodeAt(0)))
);
const db = symbol('DB').skip(optSpace)
.then(sepBy(dbConst, string(',').then(optSpace)))
// Support both DB as nullary var declaration and DB as data constants.
.map(data => data.length > 0 ? [].concat.apply([], data) : [0]);
const dw = symbol('DW').skip(optSpace)
.then(sepBy(const_16bit, string(',').then(optSpace)))
.map(data => [].concat.apply([], data));
return alt(
db,
dw,
binaryOp('SECTION', stringLiteral, seq(sectionType, indirect(numberLiteral)))
.map(([name, [sectionType, address]]) => [{
kind: 'section',
name,
sectionType,
address
// Expressions
const thin_arrow = P.string('->').skip(space)
const fat_arrow = P.string('=>').skip(space)
const assign = P.string('=').skip(space)
const typeAnnotationToken = token(P.string(':'))
const identifier = (P.regexp(/[a-z][a-zA-Z_0-9]*/).skip(exp_space)).desc('identifier')
// ID
const variable = identifier.map((id) => {
return new AST.Variable(id)
})
// arg_list = identifier, {comma, identifier}
const arg_list = P.sepBy(identifier, comma)
// optTypeAnnotation = {':', typeExpression}
const optTypeAnnotation = optional(typeAnnotationToken.then(typeExpression))
// typedIdentifier = identifier, [optTypeAnnotation, typeExpression]
const typedVariable = P.seqMap(variable, optTypeAnnotation, (v, t) => {
if (t !== undefined) {
v.userType = t
}
return v;
}
)
const typedArgList = P.sepBy(typedVariable, comma)
// literal_function = [identifier], '(', arg_list, ')', '=>' (NL, block | expression)
label.skip(optSpace),
alt(
cpuOp,
simplePseudoOp,
/*macro*/
),
(label, op) => label.concat(op)
),
cpuOp,
simplePseudoOp,
label,
optSpace.result(null)
)).skip(optSpace.then(comment.or(string(''))));
const statements: Parser =
sepBy(statement as any, string('\n'))
.map(sts => [].concat.apply([], sts).filter((x: FirstPass) => x !== null));
export function pass(input: FirstPass[]): Z80[] {
// We need an imperative walker here.
let address = 0;
const symbolTable: {[symbol: string]: number} = {};
const secondPass: (Z80|Deferred)[] = [];
for (let idx = 0; idx < input.length; idx++) {
const item = input[idx];
if (typeof item === 'number' || item.kind == 'deferred') {
secondPass[address] = item;
address++;
} else if (item.kind === 'section') {
address = item.address;
} else if (item.kind === 'label') {
const CollectionCoreLiteralParser = P.lazy((): mixed => {
const TupleParser = require('./tuple').default
const SpreadParser = P.string('...')
.then(crap)
.then(TupleParser)
.node('spread')
const SimpleListParser = P.sepBy(TupleParser, SeparatorParser).node(
'simpleList'
)
return P.sepBy(P.alt(SpreadParser, SimpleListParser), SeparatorParser).map(
(value: CollectionCoreValueType): CollectionCoreNodeType => ({
name: 'collectionCore',
value
})
)
})
import crap from './crap'
import type {
NodeType,
AssignmentNodeValueType,
AssignmentsType
} from '../types'
const Assignment = P.seq(
P.string('$').then(IdentifierParser),
P.string('=')
.trim(crap)
.then(SectionParser)
)
const Assignments = P.sepBy(Assignment, crap)
export default P.seq(
TupleParser,
P.string('where')
.trim(crap)
.then(Assignments)
)
.map(
([program, assignments]: [
NodeType,
AssignmentsType
]): AssignmentNodeValueType => ({
program,
assignments
})
)
TupleType: L => P.sepBy(L.Type, L.COMMA).wrap(L.LBRACK, L.RBRACK)
.map(r => new node.TupleType(r)),
ObjectType: L => P.sepBy(P.alt(L.DOTS, L.ObjectElement), L.COMMA).wrap(L.LBRACE, L.RBRACE)
.map((r) => {
const open = r.some(s => s === undefined);
const keyvals = r.filter(s => s !== undefined).map(s => [s[0], s[1]]);
return new node.ObjectType(new Map(keyvals), open);
}),
ObjectElement: L => P.seq(L.NAME.skip(L.COLON), L.Type),
Call: L => P.seq(L.NAME, P.sepBy(L.Expression, L.COMMA).wrap(L.LPAREN, L.RPAREN))
.map(r => new node.Call(r[0], r[1])),
FunctionArgList: L => P.sepBy(L.FunctionArg, L.COMMA).wrap(L.LPAREN, L.RPAREN),
FunctionArg: L => L.USCORE.then(L.COLON).then(L.Type),
ObjectType: L => P.sepBy(P.alt(L.DOTS, L.ObjectElement), L.COMMA).wrap(L.LBRACE, L.RBRACE)
.map((r) => {
const open = r.some(s => s === undefined);
const keyvals = r.filter(s => s !== undefined).map(s => [s[0], s[1]] as [string, node.Node]);
return new node.ObjectType(new Map(keyvals), open);
}),