...
 
Commits (4)
......@@ -76,7 +76,13 @@
"EEEEEE",
"goog",
"scrollbars",
"onoutclick"
"javascripts",
"onmouseover",
"onmouseleave",
"SVGA",
"regulex's",
"Unicodify",
"genkit"
],
// flagWords - list of words to be always considered incorrect
// This is useful for offensive words and common spelling errors.
......
......@@ -13,18 +13,21 @@
//
function initMonacoEditor ( ) {
let lastValue = ''
if ( playgroundEditor !== null && playgroundEditor !== undefined ) {
lastValue = playgroundEditor.getValue( )
playgroundEditor = undefined
document.getElementById(playgroundEditorID).innerHTML = ''
let lastValue = '';
if ( orchestra.storage.playgroundEditor !== null &&
orchestra.storage.playgroundEditor !== undefined ) {
lastValue = orchestra.storage.playgroundEditor.getValue( );
orchestra.storage.playgroundEditor = undefined;
document.getElementById( orchestra.constants.playgroundEditorID ).innerHTML = '';
}
function uriFromPath ( _path ) {
const pathName = path.resolve( _path ).replace( /\\/g, '/' )
let pathName = orchestra.externals.path.resolve( _path ).replace( /\\/g, '/' );
if ( pathName.length > 0 && pathName.charAt( 0 ) !== '/' )
pathName = '/' + pathName
return encodeURI( 'file://' + pathName )
pathName = '/' + pathName;
return encodeURI( 'file://' + pathName );
}
require.config({
......@@ -32,24 +35,24 @@
})
// workaround monaco-css not understanding the environment
self.module = undefined
self.module = undefined;
// workaround monaco-typescript not understanding the environment
self.process.browser = true
self.process.browser = true;
require([ 'vs/editor/editor.main' ], function ( ) {
const MatchLanguageName = 'CurrentMatchLanguage'
monaco.languages.register({ id: MatchLanguageName })
const MatchLanguageName = 'CurrentMatchLanguage';
monaco.languages.register({ id: MatchLanguageName });
let tokenizer = { }
let CompiledRegEx = fetchLatestCompiledRegExp( )
let tokenizer = { };
let CompiledRegEx = orchestra.quartet.fetchLatestCompiledRegExp( );
if ( CompiledRegEx !== '' )
try {
// so if the regX be horrible it would get out of the try
tokenizer = { root: [[
new RegExp( CompiledRegEx, 'm') , "match" ]]}
new RegExp( CompiledRegEx, 'm') , "match" ]]};
} catch ( error ) {
......@@ -59,8 +62,8 @@
tokenizer: tokenizer
});
playgroundEditor = monaco.editor.create(
document.getElementById( playgroundEditorID ), {
orchestra.storage.playgroundEditor = monaco.editor.create(
document.getElementById( orchestra.constants.playgroundEditorID ), {
value: lastValue,
language: MatchLanguageName,
fontFamily: 'GraphSourceCodePro',
......@@ -69,16 +72,8 @@
renderWhitespace: true,
insertSpaces: false,
}
)
})
}
//
// ─── ON RUN TEST DRIVE ──────────────────────────────────────────────────────────
//
function onPerformTestDrive ( ) {
onChangeWindowToPlayground( )
);
});
}
// ────────────────────────────────────────────────────────────────────────────────
\ No newline at end of file
// ────────────────────────────────────────────────────────────────────────────────
......@@ -8,55 +8,51 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
//
// ─── INIT ───────────────────────────────────────────────────────────────────────
//
module blueprints.block {
QuartetGenerator = new Blockly.Generator('Quartet')
//
// ─── STATEMENT BLUEPRINTS ───────────────────────────────────────────────────────
//
//
// ─── GENERATOR INIT ─────────────────────────────────────────────────────────────
//
export interface IStatement {
name: string;
children: IBlock[ ];
}
QuartetGenerator.init = workspace => {
}
//
// ─── GENERATOR FINISH ───────────────────────────────────────────────────────────
//
//
// ─── FIELDS ─────────────────────────────────────────────────────────────────────
//
QuartetGenerator.finish = code => {
return code.trim( )
};
export interface IField {
name: string;
value: string;
}
//
// ─── SCRUB NAKED VALUE ──────────────────────────────────────────────────────────
//
//
// ─── BASE BLOCK ─────────────────────────────────────────────────────────────────
//
QuartetGenerator.scrubNakedValue = line => {
return line.trim( )
};
export interface IBlock {
/** Indicates what __Quartet block__ is this */
type: string;
//
// ─── QUOTE ──────────────────────────────────────────────────────────────────────
//
/** Fields */
fields?: IField[ ];
QuartetGenerator.quote_ = text => {
return text.trim( )
};
/** Children */
children?: IStatement[ ];
}
//
// ─── SCRUB ──────────────────────────────────────────────────────────────────────
//
//
// ─── LEVEL ONE SWITCHER ─────────────────────────────────────────────────────────
//
QuartetGenerator.scrub_ = ( block, code ) => {
if ( block.id === quartetActiveBlockId )
code = `<span class="console-highlight-active-block">${ code }</span>`
export interface IIntermediateNode {
type: string;
node: blueprints.regulex.IBaseNode;
value: IBlock[ ]
}
let nextBlock = block.nextConnection && block.nextConnection.targetBlock( )
let nextCode = QuartetGenerator.blockToCode( nextBlock )
return code.trim( ) + nextCode.trim( )
}
// ────────────────────────────────────────────────────────────────────────────────
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
......@@ -8,25 +8,28 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
//
// ─── LOAD NEW WORKSPACE ─────────────────────────────────────────────────────────
//
module blueprints.recarr {
function updateWorkspaceWithNewXML ( xml ) {
loadXMLtoWorkspace( xml )
setupComposeBlock( )
setupEventListeners( )
applyAdditionalStyles( )
}
//
// ─── BLOCK OBJECT ───────────────────────────────────────────────────────────────
//
//
// ─── XML LOADER ─────────────────────────────────────────────────────────────────
//
export interface INode {
type: string;
fields?: blueprints.block.IField[ ];
statements?: IStatement[ ];
next?: INode;
}
//
// ─── RECURSIVE STATEMENT ────────────────────────────────────────────────────────
//
export interface IStatement {
name: string;
block: INode;
}
function loadXMLtoWorkspace ( xml ) {
let blockyDOM = Blockly.Xml.textToDom( xml )
Blockly.mainWorkspace.clear( )
Blockly.Xml.domToWorkspace( blockyDOM, Blockly.mainWorkspace )
}
// ────────────────────────────────────────────────────────────────────────────────
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
//
// Copyright 2016 Kary Foundation, Inc.
// Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
declare module 'regulex' {
//
// ─── EXPORTS ────────────────────────────────────────────────────────────────────
//
function parse ( regex: string ): blueprints.regulex.IRegExAST;
// ────────────────────────────────────────────────────────────────────────────────
}
declare module blueprints.regulex {
//
// ─── MAIN TREE ──────────────────────────────────────────────────────────────────
//
interface IRegExAST {
raw: string;
tree: IBaseNode[ ];
groupCount: number;
}
//
// ─── NODE ───────────────────────────────────────────────────────────────────────
//
//
// I M P O R T A N T N O T E
// This definition only provides for the very small portion of the regulex
// that we use for our compilations. Not the whole package.
//
interface IBaseNode {
type: string;
raw: string;
repeat?: {
min: number,
max: number
}
}
//
// ─── EXACT NODE ─────────────────────────────────────────────────────────────────
//
interface INodeExact extends IBaseNode {
chars: string;
}
//
// ─── SET NODE ───────────────────────────────────────────────────────────────────
//
interface INodeSet extends IBaseNode {
classes: any[ ];
ranges: string[ ];
chars: string;
exclude?: boolean;
}
//
// ─── CHOICE NODE ────────────────────────────────────────────────────────────────
//
interface INodeChoice extends IBaseNode {
branches: IBaseNode[ ][ ];
}
//
// ─── GROUP NODE ─────────────────────────────────────────────────────────────────
//
interface INodeGroup extends IBaseNode {
sub: IBaseNode[ ];
nonCapture?: boolean;
}
//
// ─── ASSERT BLOCK ───────────────────────────────────────────────────────────────
//
interface INodeAssert extends IBaseNode {
assertionType: string;
sub: IBaseNode[ ];
}
//
// ─── ASSERT LOOKAHEAD ───────────────────────────────────────────────────────────
//
interface INodeLookahead extends INodeAssert {
statement: IBaseNode;
status: boolean;
}
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
//
// Copyright 2016 Kary Foundation, Inc.
// Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
//
// This level is like a preprocessor on the regulex's AST. for handling
// the lookahead problem.
//
namespace concerto.compilers.level0 {
//
// ─── MAIN ───────────────────────────────────────────────────────────────────────
//
export function fixLookahead ( ast: blueprints.regulex.IRegExAST ):
blueprints.regulex.IRegExAST {
let topNode : blueprints.regulex.IBaseNode;
let bottomNode : blueprints.regulex.INodeLookahead;
for ( let counter = 0; counter < ast.tree.length - 1; counter++ ) {
topNode = ast.tree[ counter ];
bottomNode = <blueprints.regulex.INodeLookahead> ast.tree[ counter + 1 ];
if ( bottomNode.type === 'assert' ) {
if ( bottomNode.assertionType === 'AssertLookahead' ||
bottomNode.assertionType === 'AssertNegativeLookahead' ) {
bottomNode.type = 'lookahead';
bottomNode.statement = Object.assign({ }, topNode );
bottomNode.status = (
bottomNode.assertionType === 'AssertLookahead' );
ast.tree[ counter ] = null;
counter++;
}}}
return ast;
}
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
//
// Copyright 2016 Kary Foundation, Inc.
// Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
namespace concerto.compilers.level1 {
//
// ─── EXPORTS ────────────────────────────────────────────────────────────────────
//
/** Compiles _Regulex AST_ into _Concerto AST_ */
export function compile ( tree: blueprints.regulex.IBaseNode[ ] ) {
let ast = new Array<blueprints.block.IBlock> ( );
for ( let node of tree ) {
if ( node !== null ) {
let intermediateNode = handleOneNode( node );
if ( intermediateNode.type === 'block' )
ast.push( intermediateNode.value[ 0 ] );
else
for ( let child of intermediateNode.value )
ast.push( child );
}}
return ast;
}
//
// ─── HANDLE ONE NODE ────────────────────────────────────────────────────────────
//
function handleOneNode ( node: blueprints.regulex.IBaseNode ):
blueprints.block.IIntermediateNode {
// firs we handle the block
let intermediateNode;
switch ( node.type ) {
case 'exact':
intermediateNode =
generators.exact.generate( <blueprints.regulex.INodeExact> node );
break;
case 'charset':
intermediateNode =
generators.charset.generate( <blueprints.regulex.INodeSet> node );
break;
case 'group':
intermediateNode =
generators.group.generate( <blueprints.regulex.INodeGroup> node );
break;
case 'choice':
intermediateNode =
generators.choice.generate( <blueprints.regulex.INodeChoice> node );
break;
case 'dot':
intermediateNode =
generators.dot.generate( node );
break;
case 'lookahead':
intermediateNode =
generators.lookahead.generate( <blueprints.regulex.INodeLookahead> node );
break;
case 'assert':
intermediateNode =
generators.assert.generate( <blueprints.regulex.INodeAssert> node );
break;
}
// then we handle the repeat of the block
return generators.repeats.generate( intermediateNode );
}
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
//
// Copyright 2016 Kary Foundation, Inc.
// Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
namespace concerto.compilers.level2 {
//
// ─── STARTING ADDER ─────────────────────────────────────────────────────────────
//
export function compile ( concertoAST: blueprints.block.IBlock[ ] ):
blueprints.recarr.INode {
if ( concertoAST.length === 0 ) return null;
let firstIndex = concertoAST[ 0 ];
let children = new Array<blueprints.recarr.IStatement> ( );
// is there any children?
if ( firstIndex.children !== undefined && firstIndex.children !== null )
for ( let statement of firstIndex.children )
children.push({
name: statement.name,
block: compile( statement.children )
});
// then it's time to return the new node
if ( concertoAST.length === 1 )
return {
type: firstIndex.type,
fields: firstIndex.fields,
statements: children
}
else
return {
type: firstIndex.type,
fields: firstIndex.fields,
statements: children,
next: compile( concertoAST.splice( 1 ) )
}
}
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
//
// Copyright 2016 Kary Foundation, Inc.
// Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
namespace concerto.compilers.level3 {
//
// ─── MAIN ───────────────────────────────────────────────────────────────────────
//
export function compile ( block: blueprints.recarr.INode ) {
return `<xml xmlns="http://www.w3.org/1999/xhtml"><block type="compose" id="composer" deletable="false" x="40" y="40"><statement name="blocks">${ generateBlockXML( block ) }</statement></block></xml>`;
}
//
// ─── GENERATE XML FOR BLOCK ─────────────────────────────────────────────────────
//
function generateBlockXML ( block: blueprints.recarr.INode ): string {
let result = [ `<block type="${ block.type }" id="${ generateId( ) }">` ];
// adding fields:
if ( block.fields !== undefined && block.fields !== null )
for ( let field of block.fields )
result.push( `<field name="${ field.name }">${ field.value }</field>` );
// adding statements
if ( block.statements !== undefined )
for ( let statement of block.statements )
result.push( `<statement name="${ statement.name }">${ generateBlockXML( statement.block ) }</statement>`);
// adding the next block
if ( block.next !== null && block.next !== undefined )
result.push( `<next>${ generateBlockXML( block.next ) }</next>`);
// done
result.push('</block>');
return result.join('');
}
//
// ─── RANDOM ID GENERATOR ────────────────────────────────────────────────────────
//
function generateId ( ): string {
let result = '';
function generateRandomChar ( ): string {
let n = Math.floor( Math.random( ) * 62 );
if ( n < 10 ) return n.toString( );
if ( n < 36 ) return String.fromCharCode( n + 55 );
return String.fromCharCode( n + 61 );
}
while ( result.length < 20 ) result += generateRandomChar( );
return result;
}
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
//
// Copyright 2016 Kary Foundation, Inc.
// Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
namespace concerto.generators.genkit {
//
// ─── STATEMENT GENERATOR ────────────────────────────────────────────────────────
//
export function generateStatement ( blocks: blueprints.block.IBlock[ ],
name = 'blocks' ): blueprints.block.IStatement {
return {
name: name,
children: blocks
}
}
//
// ─── TEXT ENCODER ───────────────────────────────────────────────────────────────
//
export function encodeText ( text: string ): string {
let result = [ ];
for ( let char of text ) {
switch ( char ) {
case '<':
result.push( '&lt;' );
break;
case '>':
result.push( '&gt;' );
break;
case '/':
result.push( '\\/' );
break;
case '&':
result.push( '&amp;' );
break;
default:
result.push( char );
}
}
return result.join('');
}
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
//
// Copyright 2016 Kary Foundation, Inc.
// Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
namespace concerto.generators.assert {
//
// ─── EXPORT ─────────────────────────────────────────────────────────────────────
//
export function generate ( node: blueprints.regulex.INodeAssert ):
blueprints.block.IIntermediateNode {
if ( node.assertionType === 'AssertWordBoundary' )
return {
type: 'block',
node: node,
value: [{
type: 'boundary'
}]};
if ( node.assertionType === 'AssertNonWordBoundary' )
return {
type: 'block',
node: node,
value: [{
type: 'anything_but_boundary'
}]}
}
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
//
// Copyright 2016 Kary Foundation, Inc.
// Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
namespace concerto.generators.charset {
//
// ─── EXPORT ─────────────────────────────────────────────────────────────────────
//
export function generate ( node: blueprints.regulex.INodeSet ):
blueprints.block.IIntermediateNode {
return {
type: 'block',
node: node,
value: [
switchForSetGenerator( node )
]}}
//
// ─── GENERATOR ──────────────────────────────────────────────────────────────────
//
function switchForSetGenerator ( node: blueprints.regulex.INodeSet ):
blueprints.block.IBlock {
// Simple Range
if ( node.ranges.length === 1 && node.chars === '' &&
node.exclude !== true && node.classes.length === 0 )
return composeRangeBlock( node.ranges[ 0 ] , 'range' );
// Special Character
if ( node.ranges.length === 0 && node.chars === '' &&
node.exclude !== true && node.classes.length === 1 )
return composeSpecialCharacterBlock( node );
// Check if simple set
let simpleSet = true
if ( node.ranges !== undefined )
for ( let range of node.ranges )
if ( !( range === 'az' || range === 'AZ' || range === '09' ) )
simpleSet = false;
// composing for simple set
if ( simpleSet && node.classes.length === 0 ) return composeSimpleAlphabetBlock( node );
// composing for advanced set
return composeAdvancedSet( node );
}
//
// ─── RANGE SET BUILDER ──────────────────────────────────────────────────────────
//
function composeRangeBlock ( range: string, kind: string ): blueprints.block.IBlock {
return {
type: kind,
fields: [
{ name: 'start', value: genkit.encodeText( range[ 0 ] ) },
{ name: 'end', value: genkit.encodeText( range[ 1 ] ) }
]}}
//
// ─── SPECIAL CHARACTER ──────────────────────────────────────────────────────────
//
function composeSpecialCharacterBlock ( node: blueprints.regulex.INodeSet ):
blueprints.block.IBlock {
let quartetBlocksForClasses = {
'w': 'word',
'W': 'anything_but_word',
'd': 'digit',
'D': 'anything_but_digit',
's': 'whitespace',
'S': 'anything_but_whitespace',
'b': 'boundary',
'B': 'anything_but_boundary'
};
let block = quartetBlocksForClasses[ node.classes[ 0 ] ]
if ( block !== undefined )
return { type: block };
else
return {
type: 'free_form_regex',
fields: [{
name: 'regex', value: `\\\\${ node.classes[ 0 ] }`
}]}}
//
// ─── SIMPLE ALPHABET BLOCK ──────────────────────────────────────────────────────
//
function composeSimpleAlphabetBlock ( node: blueprints.regulex.INodeSet ):
blueprints.block.IBlock {
// fill ranges fields
let sets = {
numbers: 'FALSE',
lowercase: 'FALSE',
uppercase: 'FALSE',
};
if ( node.ranges !== undefined )
for ( let range of node.ranges )
switch ( range ) {
case '09':
sets.numbers = 'TRUE';
break;
case 'az':
sets.lowercase = 'TRUE';
break;
case 'AZ':
sets.uppercase = 'TRUE';
break;
}
// composing final stuff:
return {
type: ( node.exclude )? 'anything_but': 'alphabet',
fields:[
{ name: 'numbers' , value: sets.numbers },
{ name: 'lowercase' , value: sets.lowercase },
{ name: 'uppercase' , value: sets.uppercase },
{ name: 'other' , value: genkit.encodeText( node.chars ) },
]}}
//
// ─── ADVANCE SET ────────────────────────────────────────────────────────────────
//
function composeAdvancedSet ( node: blueprints.regulex.INodeSet ):
blueprints.block.IBlock {
let children = new Array<blueprints.block.IBlock>( );
// adding ranges
for ( let range of node.ranges )
children.push( composeRangeBlock( range, 'sigma_range' ) );
// adding other chars
if ( node.chars !== '' && node.chars !== undefined )
children.push({
type: 'sigma_chars',
fields: [{
name: 'text', value: genkit.encodeText( node.chars )
}]});
// adding special characters
if ( node.classes.length > 0 ) {
children.push({
type: 'sigma_wildcard',
fields: [{
name: 'escapes', value: node.classes.map( c => `\\\\${ c }` ).join('')
}]})};
// returning...
return {
type: ( node.exclude )? 'exclude': 'sigma',
children: [
genkit.generateStatement( children )
]}};
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
//
// Copyright 2016 Kary Foundation, Inc.
// Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
namespace concerto.generators.choice {
//
// ─── GENERATOR ──────────────────────────────────────────────────────────────────
//
export function generate ( node: blueprints.regulex.INodeChoice ):
blueprints.block.IIntermediateNode {
let children = new Array<blueprints.block.IBlock> ( );
for ( let branch of node.branches )
children.push( composeOptionBlock( branch ) );
return {
type: 'block',
node: node,
value: [{
type: 'one_of',
children: [
genkit.generateStatement( children )
]}]}};
//
// ─── COMPOS CHOICE ──────────────────────────────────────────────────────────────
//
function composeOptionBlock ( branch: blueprints.regulex.IBaseNode[ ] ):
blueprints.block.IBlock {
return {
type: 'option',
children: [
genkit.generateStatement(
compilers.level1.compile( branch )
)]}};
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
//
// Copyright 2016 Kary Foundation, Inc.
// Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
namespace concerto.generators.dot {
//
// ─── EXPORTS ────────────────────────────────────────────────────────────────────
//
export function generate ( node ) {
return {
type: 'block',
node: node,
value: [{
type: 'any'
}]}}
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
//
// Copyright 2016 Kary Foundation, Inc.
// Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
namespace concerto.generators.exact {
//
// ─── GENERATOR ──────────────────────────────────────────────────────────────────
//
export function generate ( node: blueprints.regulex.INodeExact ):
blueprints.block.IIntermediateNode {
return {
type: 'block',
node: node,
value: [{
type: 'encode',
fields: [{
name: 'text',
value: genkit.encodeText( node.chars )
}]
}]}}
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
//
// Copyright 2016 Kary Foundation, Inc.
// Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
namespace concerto.generators.group {
//
// ─── GENERATOR ──────────────────────────────────────────────────────────────────
//
export function generate ( node: blueprints.regulex.INodeGroup ):
blueprints.block.IIntermediateNode {
let children = compilers.level1.compile( node.sub );
if ( node.nonCapture === true )
return {
type: 'group',
node: node,
value: children
}
else
return {
type: 'block',
node: node,
value: [{
type: 'match',
children: [ genkit.generateStatement( children ) ]
}]
}
}
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
//
// Copyright 2016 Kary Foundation, Inc.
// Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
namespace concerto.generators.lookahead {
//
// ─── GENERATOR ──────────────────────────────────────────────────────────────────
//
export function generate ( node: blueprints.regulex.INodeLookahead ):
blueprints.block.IIntermediateNode {
return {
type: 'block',
node: node,
value: [{
type: 'lookahead',
children: [
{
name: 'blocks',
children: compilers.level1.compile([ node.statement ])
},
{
name: 'lookahead',
children: compilers.level1.compile( node.sub )
}
],
fields: [{
name: 'status',
value: ( node.status )? 'positive' : 'negative'
}]}]}}
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
//
// Copyright 2016 Kary Foundation, Inc.
// Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
namespace concerto.generators.repeats {
//
// ─── GENERATORS ─────────────────────────────────────────────────────────────────
//
export function generate ( intermediateNode: blueprints.block.IIntermediateNode ):
blueprints.block.IIntermediateNode {
// No Repeat
if ( intermediateNode.node.repeat === undefined ) return intermediateNode;
let min = intermediateNode.node.repeat.min;
let max = intermediateNode.node.repeat.max;
let blocks = intermediateNode.value;
let result : blueprints.block.IBlock[ ];
// Maybe block
if ( min === 0 && max === 1 )
result = composeStaticRepeat( 'maybe', blocks );
// One or More
else if ( min === 1 && max === Infinity )
result = composeStaticRepeat( 'one_or_more', blocks );
// Any number of
else if ( min === 0 && max === Infinity )
result = composeStaticRepeat( 'any_number_of', blocks );
// Exact Repeat
else if ( min === max )
result = composeExactRepeat( min, blocks );
// At least repeat
else if ( max === Infinity )
result = composeAtLeastRepeat( min, blocks );
// Range Repeat
else result = composeRangeRepeat( min, max, blocks );
// done
intermediateNode.value = result;
return intermediateNode;
}
//
// ─── COMPOSE MAYBE REPEAT ───────────────────────────────────────────────────────
//
function composeStaticRepeat ( repeatType: string,
blocks: blueprints.block.IBlock[ ] ):
blueprints.block.IBlock[ ] {
return [{
type: repeatType,
children: [
genkit.generateStatement( blocks )
]}]}
//
// ─── COMPOSE REPEAT TIMES ───────────────────────────────────────────────────────
//
function composeExactRepeat ( count: number,
blocks: blueprints.block.IBlock[ ] ):
blueprints.block.IBlock[ ] {
return [{
type: 'repeat',
fields: [{
name: 'count',
value: count.toString( )
}],
children: [
genkit.generateStatement( blocks )
]}]}
//
// ─── COMPOSE AT LEAST REPEAT ────────────────────────────────────────────────────
//
function composeAtLeastRepeat ( min: number,
blocks: blueprints.block.IBlock[ ] ):
blueprints.block.IBlock[ ] {
return [{
type: 'repeat_at_least',
fields: [{
name: 'count',
value: min.toString( )
}],
children: [
genkit.generateStatement( blocks )
]}]}
//
// ─── COMPOSE REPEAT IN RANGE ────────────────────────────────────────────────────
//
function composeRangeRepeat ( min: number,
max: number,
blocks: blueprints.block.IBlock[ ] ):
blueprints.block.IBlock[ ] {
return [{
type: 'repeat_in_range',
fields: [
{ name: 'start', value: min.toString( ) },
{ name: 'end', value: max.toString( ) },
],
children: [
genkit.generateStatement( blocks )
]}]}
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
//
// Copyright 2016 Kary Foundation, Inc.
// Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
namespace concerto {
//
// ─── MAIN ───────────────────────────────────────────────────────────────────────
//
export function compile ( regulexAST: blueprints.regulex.IRegExAST ) {
// running the preprocessor on the ast
let normalizedAST = compilers.level0.fixLookahead( regulexAST );
// first level compilation: Regulex AST to Concerto AST
let concertoAST = compilers.level1.compile( normalizedAST.tree );
// then we compile the concerto ast to recursive array ast
let recarrAST = compilers.level2.compile( concertoAST );
// at the end we compile the recursive array into the Quartet XML
let quartetXML = compilers.level3.compile( recarrAST );
// done!
return quartetXML.replace( /\\"|"|\n/g, match => {
if ( match === '"' )
return '\\"';
if ( match === '\n' )
return '';
});
}
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
......@@ -8,32 +8,38 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
//
// ─── SET CONSOLE REGEX ──────────────────────────────────────────────────────────
//
namespace orchestra.constants {
function setConsoleRegEx ( html ) {
document.getElementById( 'ribbon-console-regexp' ).innerHTML = html
}
//
// ─── FILE DEFAULTS ──────────────────────────────────────────────────────────────
//
//
// ─── UPDATE CONSOLE TITLE ───────────────────────────────────────────────────────
//
export const defaultFileXML = '<xml><block type="compose" deletable="false"></block></xml>'
function updateConsoleTitle ( ) {
let title = getFileName( )
let dirtStatus = ( getFileDirtStatus( ) )? ' &bullet; Not Saved' : ''
document.title = title
setConsoleTitle(`${ title }${ dirtStatus }`)
OrchestraWindow.setRepresentedFilename( title )
}
export const defaultEmptyPath = 'Undefined'
//
// ─── SET CONSOLE TITLE ──────────────────────────────────────────────────────────
//
export const defaultFileObject = {
path: defaultEmptyPath,
dirty: true,
emptyNewFile: true,
}
//
// ─── IDS ────────────────────────────────────────────────────────────────────────
//
export const EditorWindowScreenElement = 'EditorView'
export const PlaygroundWindowScreenElement = 'PlaygroundView'
export const TabsPlaceholder = 'header-tabs'
export const playgroundEditorID = 'playground-editor'
export const composeBlockIDforSVGCanvas = 'TheComposeBlockSVGCanvas'
//
// ─── SPECIAL CHARS ──────────────────────────────────────────────────────────────
//
export const __SPACE_UNICODE_STRING__ = "\\u0020"
function setConsoleTitle ( title ) {
document.getElementById( 'ribbon-console-title' ).innerHTML = title
}
// ────────────────────────────────────────────────────────────────────────────────
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
//
// Copyright 2016 Kary Foundation, Inc.
// Author: Pouya Kary <k@karyfoundation.org>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
namespace orchestra.externals {
//
// ─── INCLUDES ───────────────────────────────────────────────────────────────────
//
export const electron = require( 'electron' )
export const orchestraWindow = electron.remote.getCurrentWindow( )
export const openExternal = electron.shell.openExternal
export const regulex = require( 'regulex' )
//
// ─── NODE LOADS ─────────────────────────────────────────────────────────────────
//
export const path = require( 'path' )
export const fs = require( 'fs' )
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
......@@ -8,37 +8,41 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
//
// ─── FILE SYSTEM ────────────────────────────────────────────────────────────────
//
namespace orchestra.storage {
var currentFile = defaultFileObject
//
// ─── FILE SYSTEM ────────────────────────────────────────────────────────────────
//
//
// ─── APP MENU ───────────────────────────────────────────────────────────────────
//
export var currentFile = orchestra.constants.defaultFileObject
var OrchestraAppMenu
//
// ─── APP MENU ───────────────────────────────────────────────────────────────────
//
//
// ─── TAB MANAGER ────────────────────────────────────────────────────────────────
//
export var OrchestraAppMenu
var CurrentActiveView = 'editor'
//
// ─── TAB MANAGER ────────────────────────────────────────────────────────────────
//
//
// ─── EDITOR ─────────────────────────────────────────────────────────────────────
//
export var CurrentActiveView = 'editor'
var QuartetGenerator
var quartetActiveBlockId = ''
var workspace
var ComposeBlock
//
// ─── EDITOR ─────────────────────────────────────────────────────────────────────
//
//
// ─── PLAYGROUND ─────────────────────────────────────────────────────────────────
//
export var quartetGenerator
export var quartetActiveBlockId = ''
export var workspace: Blockly.Workspace
export var ComposeBlock
//
// ─── PLAYGROUND ─────────────────────────────────────────────────────────────────
//
export var playgroundEditor
var playgroundEditor
// ────────────────────────────────────────────────────────────────────────────────
// ────────────────────────────────────────────────────────────────────────────────
}
\ No newline at end of file
......@@ -8,51 +8,55 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
//
// ─── FILE DEFAULTS ──────────────────────────────────────────────────────────────
//
const defaultFileXML = '<xml><block type="compose" deletable="false"></block></xml>'
const defaultEmptyPath = 'Undefined'
const defaultFileObject = {
path: defaultEmptyPath,
dirty: true,
emptyNewFile: true,
}
//
// ─── ELECTRON LOADS ─────────────────────────────────────────────────────────────
//
const { ipcRenderer, clipboard } = require( 'electron' )
const { dialog } = require( 'electron' ).remote
const OrchestraWindow = require( 'electron' ).remote.getCurrentWindow( )
const openExternal = require( 'electron' ).shell.openExternal
const regulex = require('regulex')
const concerto = require('concerto-compiler')
//
// ─── NODE LOADS ─────────────────────────────────────────────────────────────────
//
const path = require( 'path' )
const fs = require( 'fs' )
//
// ─── IDS ────────────────────────────────────────────────────────────────────────
//
const EditorWindowScreenElement = 'EditorView'
const PlaygroundWindowScreenElement = 'PlaygroundView'
const TabsPlaceholder = 'header-tabs'
const playgroundEditorID = 'playground-editor'
const composeBlockIDforSVGCanvas = 'TheComposeBlockSVGCanvas'
//
// ─── SPECIAL CHARS ──────────────────────────────────────────────────────────────
//
const __SPACE_UNICODE_STRING__ = "\\u0020"
// ────────────────────────────────────────────────────────────────────────────────
namespace orchestra.quartet {
//
// ─── SETUP WORKSPACE ────────────────────────────────────────────────────────────
//
export function setupWorkspaceWithNewFile ( ) {
setupWorkspace( );
}
//
// ─── SETUP WORKSPACE ────────────────────────────────────────────────────────────
//
export function setupWorkspace ( ) {
const toolbox = document.getElementById( 'toolbox' );
storage.workspace = Blockly.inject( 'quartet-coding-view', {
collapse: false,
toolbox: toolbox,
border: false,
scrollbars: true,
trashcan: true,
media: './blockly-core/media/',
// css: false,
});
Blockly.Xml.domToWorkspace(
Blockly.Xml.textToDom( constants.defaultFileXML ), storage.workspace );
}
//
// ─── SETUP COMPOSE BLOCK ────────────────────────────────────────────────────────
//
export function setupComposeBlock ( ) {
storage.ComposeBlock = storage.workspace.getAllBlocks( )[ 0 ];
storage.workspace.getCanvas( ).setAttribute( 'id', constants.composeBlockIDforSVGCanvas );
storage.ComposeBlock.moveBy( 40, 40 );
}
//
// ─── SETUP EVENT LISTENERS ──────────────────────────────────────────────────────
//
export function setupEventListeners ( ) {
storage.workspace.addChangeListener( quartetOnUIChange );
}
// ────────────────────────────────────────────────────────────────────────────────