You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte/compiler/parse/index.js

80 lines
1.6 KiB

8 years ago
import { locate } from 'locate-character';
8 years ago
import fragment from './state/fragment.js';
8 years ago
8 years ago
const whitespace = /\s/;
8 years ago
export default function parse ( template ) {
8 years ago
const parser = {
index: 0,
template,
stack: [],
current () {
return this.stack[ this.stack.length - 1 ];
},
error ( message ) {
const { line, column } = locate( this.template, this.index );
throw new Error( `${message} (${line}:${column})` );
},
8 years ago
eat ( str, required ) {
8 years ago
if ( this.match( str ) ) {
this.index += str.length;
return true;
}
8 years ago
if ( required ) {
this.error( `Expected ${str}` );
}
8 years ago
},
match ( str ) {
return this.template.slice( this.index, this.index + str.length ) === str;
},
allowWhitespace () {
while ( this.index < this.template.length && whitespace.test( this.template[ this.index ] ) ) {
this.index++;
}
},
readUntil ( pattern ) {
const match = pattern.exec( this.template.slice( this.index ) );
return this.template.slice( this.index, match ? ( this.index += match.index ) : this.template.length );
},
remaining () {
return this.template.slice( this.index );
8 years ago
},
requireWhitespace () {
if ( !whitespace.test( this.template[ this.index ] ) ) {
this.error( `Expected whitespace` );
}
this.allowWhitespace();
8 years ago
}
};
8 years ago
8 years ago
const html = {
8 years ago
start: 0,
end: template.length,
type: 'Fragment',
children: []
};
8 years ago
let css = null;
let js = null;
8 years ago
8 years ago
parser.stack.push( html );
8 years ago
let state = fragment;
8 years ago
while ( parser.index < parser.template.length ) {
8 years ago
state = state( parser ) || fragment;
8 years ago
}
8 years ago
return { html, css, js };
8 years ago
}