eval(readFile("Amarin_Test3_Library")) //[instrument name, program number, on/off instrument_list = [["piano", 0, 0], ["xylophone", 13, 0], ["aguitar", 24, 0], ["eguitar", 29, 0], ["drums", 0, 0] ] reset_program_state = function() { instrument_list = [["piano", 0, 0], ["xylophone", 13, 0], ["aguitar", 24, 0], ["eguitar", 29, 0], ["drums", -1, 0]] midi_file = [] heap = [] number_of_tracks = 1 } get_instrument = function(name) { var ret = [] var i for (i = 0; i < instrument_list.length; i++) { if (instrument_list[i][0] == name) { ret = instrument_list[i] break } } return ret } set_instrument = function(name) { var i for (i = 0; i < instrument_list.length; i++) { if (instrument_list[i][0] == name) { instrument_list[i][2] = 1 break } } } ometa A <: Parser { //numbers and words d = digit, n = d:x n:y -> (x+y) | d, a = letter, w = a:x w:y -> (x+y) | a, space = ~'\n' super('space'), variable = spaces w:x ? (x != 'v') -> ['?', x], literal = spaces n:x -> [parseInt(x)], //number lists nlist = listOf('literal', ''), //tune element = literal | variable, //for tunes, we have the extra ^ and v operations tune_op = "(" tune_op_add:x ")" -> x | "^" tune_expr_list:x -> ['^'].concat(x) | "v" tune_expr_list:x -> ['v'].concat(x) | element:x -> x, tune_op_mul = tune_op_mul:x "*" tune_op:y -> ['*'].concat([x]).concat([y]) | tune_op_mul:x "/" tune_op:y -> ['/'].concat([x]).concat([y]) | tune_op, tune_op_add = tune_op_add:x "+" tune_op_mul:y -> ['+'].concat([x]).concat([y]) | tune_op_add:x "-" tune_op_mul:y -> ['-'].concat([x]).concat([y]) | tune_op_mul, tune_expr = tune_op_add, tune_expr_list = listOf('tune_expr', ''), //for other parts of the melody, it's just math op = "(" op_add:x ")" -> x | element:x -> x, op_mul = op_mul:x "*" op:y -> ['*'].concat([x]).concat([y]) | op_mul:x "/" op:y -> ['/'].concat([x]).concat([y]) | op, op_add = op_add:x "+" op_mul:y -> ['+'].concat([x]).concat([y]) | op_add:x "-" op_mul:y -> ['-'].concat([x]).concat([y]) | op_mul, expr = op_add, expr_list = listOf('expr', ''), tune = "\"" tune_expr_list:x "\"" -> x, timing = ":" expr_list:x ":" -> x, scale = "$" expr_list:x "$" -> x, position = "@" expr_list:x ? (x.length == 1) -> x, melody_literal = tune:x1 "\n" timing:x2 "\n" scale:x3 "\n" position:x4 -> ['!', [x1, x2, x3, x4]], melody_variable = variable, melody_element = melody_literal | melody_variable, optional_newlines = "\n" optional_newlines | "", melody_op = "(" melody_op_concat:x ")" -> x | melody_element, melody_op_and = melody_op_and:x optional_newlines "&" optional_newlines melody_op:y -> ['&', x, y] | melody_op, melody_op_concat = melody_op_concat:x optional_newlines "." optional_newlines melody_op_and:y -> ['.', x, y] | melody_op_and, melody_expr = melody_op_concat, //definitions definition = optional_newlines variable:x "=" optional_newlines melody_expr:y ? (get_instrument(x[1]).length > 0 && get_instrument(x[1])[2] == 0) -> { number_of_tracks++ set_instrument(x[1]) add_var_to_heap([x[1]].concat([y])) } | optional_newlines variable:x "=" optional_newlines melody_expr:y ? (get_instrument(x[1]).length == 0) -> add_var_to_heap([x[1]].concat([y])), definitions = listOf('definition', '\n'), program = definitions -> { write2file(file_header()) var i var channel = 0 for (i = 0; i < instrument_list.length; i++) { if (instrument_list[i][2] == 1) { var heap_melody = get_var_from_heap(instrument_list[i][0]) ir = melody2ir(heap_melody[1]) var midi_events = [] var final_channel = channel if (instrument_list[i][0] == "drums") final_channel = 9 midi_events = midi_events.concat(program_change(final_channel, instrument_list[i][1])) midi_events = midi_events.concat(ir2midi(ir,final_channel)) midi_events = midi_events.concat(end_of_track()) write2file(track_header(midi_events.length)) write2file(midi_events) if (final_channel != 9) channel++ if (channel == 9) channel++ } } create_binary() } } A.matchAll('"0 0 0 0 + x + 2 + ^ (y + 4) * 5 v 1 5 6"', 'tune') A.matchAll(':0 0 0 0 + x + 2 + (y + 4) * 5 1 5 6:', 'timing') A.matchAll('$0 0 0 0 + x + 2 + (y + 4) * 5 1 5 6$', 'scale') A.matchAll('@0 + 2', 'position') str01 = '" x 1 2 3 4 5 " : x 24 24 24 24 24 : $ 1 3 5 6 8 10 12 13 $ @ 48 & " x 1 2 3 4 5 " : x 24 24 24 24 24 : $ 1 3 5 6 8 10 12 13 $ @ 48 ' A.matchAll(str01, 'melody_expr') reset_program_state() str02 = 'x = " 1 2 3 4 5 " : 24 24 24 24 24 : $ 1 3 5 6 8 10 12 13 $ @ 48 y = " x-2 " : x : $ x $ @ x piano = x & y' A.matchAll(str02, 'program') heap = [] str03 = 'y = x' A.matchAll(str03, 'definition') str04 = 'z= "^ y" :y: $y$ @48' A.matchAll(str04, 'definition') str05 = 'a = x & z' A.matchAll(str05, 'definition') str06 = 'x = " 1 2 3 4 5 " : 24 24 24 24 24 : $ 1 3 5 6 8 10 12 13 $ @ 48 y = x z= "^ y" :y: $y$ @48 a = x & z ' A.matchAll(str06, 'definitions')