Added .cvsignore.
[ahxm.git] / compiler.y
blob77320d6234d64ac35ccf6f82d06ffa1b4ebe8d0e
1 %{
2 /*
4 Ann Hell Ex Machina - Music Software
5 Copyright (C) 2003/2004 Angel Ortega <angel@triptico.com>
7 compiler.y - Scripting language YACC parser
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 http://www.triptico.com
27 #include "config.h"
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <math.h>
34 #include "core.h"
35 #include "event.h"
37 /*******************
38 Data
39 ********************/
41 int yylex(void);
42 void yyerror(char * s);
44 /* injecting code functions (defined in compiler.l) */
45 int push_code(char * code, int times, int dyn);
46 int push_code_from_file(char * file);
48 /* current track */
49 int _track;
51 /* current time */
52 double _cur_time;
54 /* note globals */
55 static double _length;
56 static int _octave;
57 static int _transpose;
58 static double _staccato;
59 static float _volume;
60 static double _gliss;
62 /* parser debugging */
64 #define DEBUGF if(_debug)printf
66 /* named blocks */
68 struct _named_block
70 char name[64];
71 char * block;
74 static struct _named_block * _named_blocks=NULL;
75 static int _n_named_blocks=0;
76 static int _named_blocks_size=0;
78 /* group info */
79 struct _group
81 double start;
82 double gliss;
83 double max;
86 static struct _group * _groups=NULL;
87 static int _n_groups=0;
88 static int _groups_size=0;
90 /* mark info */
91 struct _mark
93 char name[64];
94 double time;
97 static struct _mark * _marks=NULL;
98 static int _n_marks=0;
99 static int _marks_size=0;
101 /* arpeggiator */
102 struct _arp
104 double delay;
105 int transpose;
106 float volume;
107 int track;
110 static struct _arp * _arps=NULL;
111 static int _n_arps=0;
112 static int _arps_size=0;
114 static double _arp_delay;
115 static int _arp_transpose;
116 static float _arp_volume;
117 static int _arp_track;
119 /*******************
120 Code
121 ********************/
123 void _c_err(char * e1, char * e2, char * e3)
124 /* reports an error from the compiler */
126 printf("Compiler error:");
127 if(e1 != NULL) printf(" %s", e1);
128 if(e2 != NULL) printf(" %s", e2);
129 if(e3 != NULL) printf(" %s", e3);
130 printf("\n");
134 static void _forward(void)
135 /* moves forward current time by current length */
137 /* just add current length to time cursor */
138 _cur_time += _length;
140 /* quantizations could be done here */
144 /* named blocks */
146 static int _set_named_block(char * name, char * block)
147 /* sets a named block */
149 int n;
151 /* find first if block is previously defined */
152 for(n=0;n < _n_named_blocks;n++)
154 if(strcmp(name, _named_blocks[n].name) == 0)
156 free(_named_blocks[n].block);
157 break;
161 if(n == _n_named_blocks)
163 /* need to expand? */
164 if(_n_named_blocks == _named_blocks_size)
166 _named_blocks_size += 4;
168 _named_blocks=(struct _named_block *)
169 realloc(_named_blocks,
170 _named_blocks_size *
171 sizeof(struct _named_block));
174 _n_named_blocks++;
177 strncpy(_named_blocks[n].name, name, sizeof(_named_blocks[n].name));
178 _named_blocks[n].block=block;
180 return(1);
184 static void _insert_named_block(char * name)
185 /* inserts a named block */
187 int n;
189 for(n=0;n < _n_named_blocks;n++)
191 if(strcmp(name, _named_blocks[n].name) == 0)
193 push_code(_named_blocks[n].block, 1, 0);
194 return;
198 _c_err("block-not-found", name, NULL);
202 static void _insert_file(char * filename)
204 if(!push_code_from_file(filename))
205 _c_err("script-not-found", filename, NULL);
209 /* groups */
211 static int _push_group(void)
212 /* starts a new group of notes */
214 if(_n_groups == _groups_size)
216 _groups_size += 4;
218 _groups=(struct _group *) realloc(_groups,
219 _groups_size * sizeof(struct _group));
222 _groups[_n_groups].start=_cur_time;
223 _groups[_n_groups].gliss=0.0;
224 _groups[_n_groups].max=0.0;
226 _n_groups++;
228 return(1);
232 static int _next_group_part(void)
233 /* part delimiter */
235 if(_n_groups == 0)
237 _c_err("missing-start-of-group", NULL, NULL);
238 return(0);
241 /* store maximum frame */
242 if(_groups[_n_groups - 1].max < _cur_time)
243 _groups[_n_groups - 1].max=_cur_time;
245 /* add glissando delay */
246 _groups[_n_groups - 1].gliss += _gliss;
248 /* rewind */
249 _cur_time=_groups[_n_groups - 1].start + _groups[_n_groups - 1].gliss;
251 return(1);
255 static int _pop_group(void)
256 /* finishes a group, moving the frame to the end of the longer part */
258 if(_n_groups == 0)
260 _c_err("missing-start-of-group", NULL, NULL);
261 return(0);
264 _n_groups--;
266 _cur_time=_groups[_n_groups].max;
268 return(1);
272 /* marks */
274 static void _add_mark(char * name)
275 /* creates a new mark */
277 if(_n_marks == _marks_size)
279 _marks_size += 4;
281 _marks=(struct _mark *) realloc(_marks,
282 _marks_size * sizeof(struct _mark));
285 strncpy(_marks[_n_marks].name, name, sizeof(_marks[_n_marks].name));
286 _marks[_n_marks].time=_cur_time;
288 _n_marks++;
292 static void _find_mark(char * name, int set)
293 /* finds a mark by name, optionally moving time cursor there */
295 int n;
297 for(n=0;n < _n_marks;n++)
299 if(strcmp(_marks[n].name, name) == 0)
301 if(set)
303 if(_cur_time > _marks[n].time)
304 _c_err("mark-overpassed", name, NULL);
305 else
306 _cur_time=_marks[n].time;
308 else
309 if(_cur_time != _marks[n].time)
310 _c_err("mark-mismatch", name, NULL);
312 return;
316 _c_err("mark-not-found", name, NULL);
320 /* arpeggiator */
322 static void _arp_default(void)
323 /* resets arpeggiator values to the default ones */
325 _arp_delay=0.0;
326 _arp_transpose=0;
327 _arp_volume=1.0;
328 _arp_track=_track;
332 static void _add_arp(void)
333 /* adds an arpeggiator note */
335 /* if the note is exactly the same, do nothing */
336 if(_arp_delay == 0.0 && _arp_transpose == 0 &&
337 _arp_volume == 1.0 && _arp_track == _track)
338 return;
340 if(_n_arps == _arps_size)
342 _arps_size += 4;
344 _arps=(struct _arp *) realloc(_arps,
345 _arps_size * sizeof(struct _arp));
348 _arps[_n_arps].delay=_arp_delay;
349 _arps[_n_arps].transpose=_arp_transpose;
350 _arps[_n_arps].volume=_arp_volume;
351 _arps[_n_arps].track=_arp_track;
353 _n_arps++;
354 _arp_default();
358 /* events */
360 static void _add_note_event(int note)
361 /* adds a note event */
363 int n;
364 int np;
365 union event1 e1;
367 /* calculate the note */
368 np=note + _transpose + (_octave * 12);
370 /* is note out of range? */
371 if(np < 0 || np > 127)
373 _c_err("note-out-of-range", NULL, NULL);
374 return;
377 e1.note.type=EV1_NOTE;
378 e1.note.time=_cur_time;
379 e1.note.trk_id=_track;
380 e1.note.note=np;
381 e1.note.len=_length * _staccato;
382 e1.note.vol=_volume;
384 new_event1(&e1);
386 printf("Note(%d): %lf %d %lf %lf\n",
387 _track, _cur_time, np, _length, _volume);
389 /* add arpeggiator repetitions */
390 for(n=0;n < _n_arps;n++)
392 e1.note.time=_cur_time + _arps[n].delay;
393 e1.note.trk_id=_arps[n].track;
394 e1.note.note=np + _arps[n].transpose;
395 e1.note.vol=_volume * _arps[n].volume;
397 new_event1(&e1);
402 static void _add_tempo_event(int trk_id, double tempo)
404 union event1 e1;
406 e1.tempo.type=EV1_TEMPO;
407 e1.tempo.time=_cur_time;
408 e1.tempo.trk_id=trk_id;
409 e1.tempo.tempo=tempo;
410 new_event1(&e1);
414 static void _add_meter_event(int trk_id, int num, int den)
416 union event1 e1;
418 e1.meter.type=EV1_METER;
419 e1.meter.time=_cur_time;
420 e1.meter.trk_id=trk_id;
421 e1.meter.num=num;
422 e1.meter.den=den;
423 new_event1(&e1);
426 static void _add_measure_event(void)
428 union event1 e1;
430 e1.generic.type=EV1_MEASURE;
431 e1.generic.time=_cur_time;
432 e1.generic.trk_id=-1;
433 new_event1(&e1);
437 static void _init_track(void)
438 /* sets the default values for a new track */
440 _cur_time=0.0;
441 _length=0.0;
442 _transpose=0;
443 _staccato=0.8;
444 _volume=0.75;
445 _octave=5;
446 _gliss=0;
448 /* groups should not cross track boundaries */
449 _n_groups=0;
451 /* reset arpeggiator */
452 _n_arps=0;
453 _arp_default();
459 %union {
460 int i;
461 double d;
462 char * p;
465 %token <i> P_INTEGER S_INTEGER
466 %token <d> P_REAL S_REAL
467 %token <i> NOTE_P NOTE_T3 NOTE_T5
468 %token <p> NEW_MARK GOTO_MARK ASSERT_MARK
470 %token <p> BLOCK BLK_ASSIGN BLK_INSERT FILE_INSERT
472 %token <p> SS_STR
473 %token <i> SS_FRAMES
475 %token SS_SEP SS_WAV SS_PAT SS_SUSTAIN
476 %token SS_EFF_DELAY SS_EFF_ECHO SS_EFF_COMB SS_EFF_ALLPASS
477 %token SS_EFF_FLANGER SS_EFF_WOBBLE SS_EFF_SQWOBBLE SS_EFF_FADER
479 %type <i> integer note note_pitch rest
480 %type <d> real p_number number note_length
482 %type <d> arp_list arp_note
486 script:
487 script stmt { ; }
488 | /* NULL */
491 stmt:
492 note {
493 /* note event */
494 _add_note_event($1);
495 _forward();
497 | rest {
498 /* rest */
499 _forward();
501 | 'z' note_length {
502 /* zero note */
503 _length=$2;
505 | 'o' P_INTEGER {
506 /* absolute octave */
507 _octave=$2;
509 | 'o' S_INTEGER {
510 /* relative octave */
511 _octave += $2;
513 | 'v' P_REAL {
514 /* absolute volume */
515 _volume=(float)$2;
517 | 'v' S_REAL {
518 /* relative volume */
519 _volume += (float)$2;
521 | 't' integer {
522 /* transpose */
523 _transpose=$2;
525 | 's' p_number {
526 /* staccato */
527 _staccato=$2;
530 | '<' {
531 /* start of group */
532 _push_group();
534 | ';' {
535 /* group delimiter */
536 _next_group_part();
538 | '>' {
539 /* end of group */
540 _pop_group();
542 | 'l' note_length {
543 /* glissando */
544 _gliss=$2;
547 | '|' {
548 /* measure mark event */
549 _add_measure_event();
552 | NEW_MARK {
553 /* add new mark */
554 _add_mark($1);
556 | GOTO_MARK {
557 /* go to mark */
558 _find_mark($1, 1);
560 | ASSERT_MARK {
561 /* assert mark */
562 _find_mark($1, 0);
565 | '\\' {
566 /* new track */
568 _track++;
569 _init_track();
571 | 'T' p_number {
572 /* tempo setting */
573 _add_tempo_event(-1, $2);
575 | 'M' P_INTEGER '/' P_INTEGER {
576 /* meter (time signature) setting */
577 _add_meter_event(-1, $2, $4);
580 | BLOCK '*' P_INTEGER {
581 /* repeat block */
582 push_code($1, $3, 1);
584 | BLOCK BLK_ASSIGN {
585 /* assign block */
586 _set_named_block($2, $1);
588 | BLK_INSERT {
589 /* insert named block */
590 _insert_named_block($1);
592 | FILE_INSERT {
593 /* insert file */
594 _insert_file($1);
597 | arp { ; }
599 | ss_cmd { DEBUGF("ss_cmd\n"); }
603 integer:
604 P_INTEGER { $$ = $1; }
605 | S_INTEGER { $$ = $1; }
608 real:
609 P_REAL { $$ = $1; }
610 | S_REAL { $$ = $1; }
613 p_number:
614 P_INTEGER { $$ = (double) $1; }
615 | P_REAL { $$ = $1; }
618 number:
619 integer { $$ = (double) $1; }
620 | real { $$ = $1; }
623 note:
624 note_pitch { $$ = $1; }
625 | note note_length { $$ = $1; _length=$2; }
626 | note '~' number { $$ = $1; DEBUGF("imm volume: %lf\n", $3); }
629 note_pitch:
630 NOTE_P { $$ = $1; }
631 | note_pitch '&' { $$ = $1 - 1; }
632 | note_pitch '#' { $$ = $1 + 1; }
633 | note_pitch '\'' { $$ = $1 + 12; }
634 | note_pitch ',' { $$ = $1 - 12; }
637 note_length:
638 P_INTEGER { $$ = 1 / (double) $1; }
639 | note_length NOTE_T3 { $$ = $1 * 2.0 / 3.0; }
640 | note_length NOTE_T5 { $$ = $1 * 4.0 / 5.0; }
641 | note_length '*' p_number { $$ = $1 * $3; }
642 | note_length '.' { $$ = $1 * 1.5; }
645 rest:
646 'r' { ; }
647 | rest note_length {
648 /* rest with length */
649 _length=$2;
653 arp:
654 'x' {
655 /* empty arpeggiator */
656 _n_arps=0;
657 _arp_default();
659 | 'x' arp_list { ; }
662 arp_list:
663 arp_note {
664 /* first arpeggiator note */
665 _n_arps=0;
666 _add_arp();
668 | arp_list ',' arp_note {
669 /* rest of arpeggiator notes */
670 _add_arp();
674 arp_note:
675 note_length {
676 /* arpeggiator delay */
677 _arp_delay=$1;
679 | arp_note '~' number {
680 /* arpeggiator volume */
681 _arp_volume=(float)$3;
683 | arp_note S_INTEGER {
684 /* arpeggiator transpose */
685 _arp_transpose=$2;
687 | arp_note '@' P_INTEGER {
688 /* arpeggiator track */
689 _arp_track=$3;
693 ss_cmd:
694 SS_WAV SS_STR { DEBUGF("SS_WAV: %s\n", $2); }
695 | SS_PAT SS_STR { DEBUGF("SS_PAT: %s\n", $2); }
696 | SS_SUSTAIN SS_FRAMES { DEBUGF("SS_SUSTAIN: %d\n", $2); }
697 | SS_EFF_DELAY S_INTEGER SS_FRAMES { DEBUGF("delay chan: %d frames: %d\n", $2, $3); }
698 | SS_EFF_ECHO S_INTEGER SS_FRAMES number { DEBUGF("echo chan: %d frames: %d gain: %lf\n", $2, $3, $4); }
699 | SS_EFF_FADER S_INTEGER SS_FRAMES number number { DEBUGF("fader chan: %d frames: %d %lf .. %lf\n", $2, $3, $4, $5); }
704 void yyerror(char * s)
706 printf("yyerror: %s\n", s);
709 #ifdef QQ
710 int main(void)
712 _init_track();
714 push_code("!this-is-a-mark", 1, 0);
715 push_code("< c1 ; e& ; g>", 1, 0);
716 push_code("^this-is-a-mark", 1, 0);
717 push_code("x4,2-1,2.+4", 1, 0);
718 push_code("a b'' c,, ", 1, 0);
719 push_code("v0.1 (d8 v+0.1)*10", 1, 0);
720 push_code("t1 t-2 t+3", 1, 0);
721 push_code("{ fader -1 100ms 0 1 } r r4. z2 `room_kit.ahs` o4 o+1 o-2 ", 1, 0);
722 push_code("{ sustain 100ms }", 1, 0);
723 push_code("T120.0 M4/4 z8 abcde T80 (edcba)=drum1 $drum1 $drum1 ((a&b)*3 (cd)*2)*10", 2, 0);
725 yyparse();
727 printf("Exiting main...\n");
728 exit(0);
730 #endif
732 int compile(char * code)
734 _track=0;
735 event1_clear();
737 /* default settings */
738 _add_tempo_event(-2, 120.0);
739 _add_meter_event(-2, 4, 4);
740 _init_track();
742 push_code(code, 1, 0);
744 yyparse();
746 return(1);