2016-10-22 23:56:07 +00:00
//: Allow Mu programs to log facts just like we've been doing in C++ so far.
2015-07-28 05:47:17 +00:00
: ( scenario trace )
2016-03-08 09:30:14 +00:00
def main [
2016-10-22 23:56:07 +00:00
trace 1 , [ foo ] , [ this is a trace in Mu ]
2015-07-28 05:47:17 +00:00
]
2016-10-22 23:56:07 +00:00
+ foo : this is a trace in Mu
2015-07-28 05:47:17 +00:00
: ( before " End Primitive Recipe Declarations " )
TRACE ,
: ( before " End Primitive Recipe Numbers " )
2015-11-06 19:06:58 +00:00
put ( Recipe_ordinal , " trace " , TRACE ) ;
2015-10-01 07:13:45 +00:00
: ( before " End Primitive Recipe Checks " )
2015-07-28 05:47:17 +00:00
case TRACE : {
2015-10-01 07:13:45 +00:00
if ( SIZE ( inst . ingredients ) < 3 ) {
2017-05-26 23:43:18 +00:00
raise < < maybe ( get ( Recipe , r ) . name ) < < " 'trace' takes three or more ingredients rather than ' " < < to_original_string ( inst ) < < " ' \n " < < end ( ) ;
2015-08-13 23:36:51 +00:00
break ;
2015-07-28 05:47:17 +00:00
}
2015-10-01 07:13:45 +00:00
if ( ! is_mu_number ( inst . ingredients . at ( 0 ) ) ) {
2016-05-21 05:09:06 +00:00
raise < < maybe ( get ( Recipe , r ) . name ) < < " first ingredient of 'trace' should be a number (depth), but got ' " < < inst . ingredients . at ( 0 ) . original_string < < " ' \n " < < end ( ) ;
2015-08-13 23:53:32 +00:00
break ;
}
2016-09-17 06:52:15 +00:00
if ( ! is_literal_text ( inst . ingredients . at ( 1 ) ) ) {
2016-05-21 05:09:06 +00:00
raise < < maybe ( get ( Recipe , r ) . name ) < < " second ingredient of 'trace' should be a literal string (label), but got ' " < < inst . ingredients . at ( 1 ) . original_string < < " ' \n " < < end ( ) ;
2015-08-13 23:53:32 +00:00
break ;
}
2015-10-01 07:13:45 +00:00
break ;
}
: ( before " End Primitive Recipe Implementations " )
case TRACE : {
2016-03-14 03:26:47 +00:00
int depth = ingredients . at ( 0 ) . at ( 0 ) ;
2015-08-13 23:53:32 +00:00
string label = current_instruction ( ) . ingredients . at ( 1 ) . name ;
ostringstream out ;
2016-10-20 05:10:35 +00:00
for ( int i = 2 ; i < SIZE ( current_instruction ( ) . ingredients ) ; + + i ) {
2016-05-25 01:32:18 +00:00
if ( i > 2 ) out < < ' ' ;
2016-11-12 07:30:16 +00:00
out < < inspect ( current_instruction ( ) . ingredients . at ( i ) , ingredients . at ( i ) ) ;
2015-08-13 23:53:32 +00:00
}
trace ( depth , label ) < < out . str ( ) < < end ( ) ;
2015-07-28 05:47:17 +00:00
break ;
}
2015-11-28 08:36:37 +00:00
//: simpler limited version of 'trace'
2015-08-11 06:15:00 +00:00
: ( before " End Primitive Recipe Declarations " )
STASH ,
: ( before " End Primitive Recipe Numbers " )
2015-11-06 19:06:58 +00:00
put ( Recipe_ordinal , " stash " , STASH ) ;
2015-10-02 00:30:14 +00:00
: ( before " End Primitive Recipe Checks " )
case STASH : {
break ;
}
2015-08-11 06:15:00 +00:00
: ( before " End Primitive Recipe Implementations " )
case STASH : {
ostringstream out ;
2016-10-20 05:10:35 +00:00
for ( int i = 0 ; i < SIZE ( current_instruction ( ) . ingredients ) ; + + i ) {
2016-05-25 01:32:18 +00:00
if ( i ) out < < ' ' ;
2016-11-12 07:30:16 +00:00
out < < inspect ( current_instruction ( ) . ingredients . at ( i ) , ingredients . at ( i ) ) ;
2015-08-11 06:15:00 +00:00
}
2015-10-07 06:38:28 +00:00
trace ( 2 , " app " ) < < out . str ( ) < < end ( ) ;
2015-08-11 06:15:00 +00:00
break ;
}
: ( scenario stash_literal_string )
2016-03-08 09:30:14 +00:00
def main [
2015-08-11 06:15:00 +00:00
stash [ foo ]
]
+ app : foo
: ( scenario stash_literal_number )
2016-03-08 09:30:14 +00:00
def main [
2015-08-24 20:40:21 +00:00
stash [ foo : ] , 4
2015-08-11 06:15:00 +00:00
]
+ app : foo : 4
: ( scenario stash_number )
2016-03-08 09:30:14 +00:00
def main [
2016-09-17 07:43:13 +00:00
1 : num < - copy 34
stash [ foo : ] , 1 : num
2015-08-11 06:15:00 +00:00
]
+ app : foo : 34
: ( code )
2016-11-12 07:30:16 +00:00
string inspect ( const reagent & r , const vector < double > & data ) {
2015-08-11 06:15:00 +00:00
if ( is_literal ( r ) )
2016-05-25 01:32:18 +00:00
return r . name ;
2016-11-12 07:30:16 +00:00
// End inspect Special-cases(r, data)
2015-08-11 06:15:00 +00:00
ostringstream out ;
2016-10-20 05:10:35 +00:00
for ( long long i = 0 ; i < SIZE ( data ) ; + + i ) {
2016-05-25 01:32:18 +00:00
if ( i ) out < < ' ' ;
out < < no_scientific ( data . at ( i ) ) ;
}
2015-08-11 06:15:00 +00:00
return out . str ( ) ;
}
2015-07-28 05:47:17 +00:00
: ( before " End Primitive Recipe Declarations " )
2015-10-07 05:15:45 +00:00
HIDE_ERRORS ,
2015-07-28 05:47:17 +00:00
: ( before " End Primitive Recipe Numbers " )
2015-11-06 19:06:58 +00:00
put ( Recipe_ordinal , " hide-errors " , HIDE_ERRORS ) ;
2015-10-02 00:30:14 +00:00
: ( before " End Primitive Recipe Checks " )
2015-10-07 05:15:45 +00:00
case HIDE_ERRORS : {
2015-10-02 00:30:14 +00:00
break ;
}
2015-07-28 05:47:17 +00:00
: ( before " End Primitive Recipe Implementations " )
2015-10-07 05:15:45 +00:00
case HIDE_ERRORS : {
Hide_errors = true ;
2015-07-28 05:47:17 +00:00
break ;
}
: ( before " End Primitive Recipe Declarations " )
2015-10-07 05:15:45 +00:00
SHOW_ERRORS ,
2015-07-28 05:47:17 +00:00
: ( before " End Primitive Recipe Numbers " )
2015-11-06 19:06:58 +00:00
put ( Recipe_ordinal , " show-errors " , SHOW_ERRORS ) ;
2015-10-02 00:30:14 +00:00
: ( before " End Primitive Recipe Checks " )
2015-10-07 05:15:45 +00:00
case SHOW_ERRORS : {
2015-10-02 00:30:14 +00:00
break ;
}
2015-07-28 05:47:17 +00:00
: ( before " End Primitive Recipe Implementations " )
2015-10-07 05:15:45 +00:00
case SHOW_ERRORS : {
Hide_errors = false ;
2015-07-28 05:47:17 +00:00
break ;
}
: ( before " End Primitive Recipe Declarations " )
2015-10-07 06:38:28 +00:00
TRACE_UNTIL ,
2015-07-28 05:47:17 +00:00
: ( before " End Primitive Recipe Numbers " )
2015-11-06 19:06:58 +00:00
put ( Recipe_ordinal , " trace-until " , TRACE_UNTIL ) ;
2015-10-02 00:30:14 +00:00
: ( before " End Primitive Recipe Checks " )
2015-10-07 06:38:28 +00:00
case TRACE_UNTIL : {
2015-10-02 00:30:14 +00:00
break ;
}
2015-07-28 05:47:17 +00:00
: ( before " End Primitive Recipe Implementations " )
2015-10-07 06:38:28 +00:00
case TRACE_UNTIL : {
2015-07-28 05:47:17 +00:00
if ( Trace_stream ) {
2015-10-07 06:38:28 +00:00
Trace_stream - > collect_depth = ingredients . at ( 0 ) . at ( 0 ) ;
2015-07-28 05:47:17 +00:00
}
break ;
}
: ( before " End Primitive Recipe Declarations " )
_DUMP_TRACE ,
: ( before " End Primitive Recipe Numbers " )
2015-11-06 19:06:58 +00:00
put ( Recipe_ordinal , " $dump-trace " , _DUMP_TRACE ) ;
2015-10-02 00:30:14 +00:00
: ( before " End Primitive Recipe Checks " )
case _DUMP_TRACE : {
break ;
}
2015-07-28 05:47:17 +00:00
: ( before " End Primitive Recipe Implementations " )
case _DUMP_TRACE : {
if ( ingredients . empty ( ) ) {
DUMP ( " " ) ;
}
else {
DUMP ( current_instruction ( ) . ingredients . at ( 0 ) . name ) ;
}
break ;
}
: ( before " End Primitive Recipe Declarations " )
_CLEAR_TRACE ,
: ( before " End Primitive Recipe Numbers " )
2015-11-06 19:06:58 +00:00
put ( Recipe_ordinal , " $clear-trace " , _CLEAR_TRACE ) ;
2015-10-02 00:30:14 +00:00
: ( before " End Primitive Recipe Checks " )
case _CLEAR_TRACE : {
break ;
}
2015-07-28 05:47:17 +00:00
: ( before " End Primitive Recipe Implementations " )
case _CLEAR_TRACE : {
2015-10-19 22:07:54 +00:00
if ( Trace_stream ) Trace_stream - > past_lines . clear ( ) ;
2015-07-28 05:47:17 +00:00
break ;
}
2015-10-19 22:53:09 +00:00
: ( before " End Primitive Recipe Declarations " )
_SAVE_TRACE ,
: ( before " End Primitive Recipe Numbers " )
2015-11-06 19:06:58 +00:00
put ( Recipe_ordinal , " $save-trace " , _SAVE_TRACE ) ;
2015-10-19 22:53:09 +00:00
: ( before " End Primitive Recipe Checks " )
case _SAVE_TRACE : {
break ;
}
: ( before " End Primitive Recipe Implementations " )
case _SAVE_TRACE : {
2018-07-26 05:25:12 +00:00
if ( Save_trace ) Trace_stream - > save ( ) ;
2015-10-19 22:53:09 +00:00
break ;
}
2015-07-28 05:47:17 +00:00
//:: 'cheating' by using the host system
: ( before " End Primitive Recipe Declarations " )
_PRINT ,
: ( before " End Primitive Recipe Numbers " )
2015-11-06 19:06:58 +00:00
put ( Recipe_ordinal , " $print " , _PRINT ) ;
2015-10-02 00:30:14 +00:00
: ( before " End Primitive Recipe Checks " )
case _PRINT : {
break ;
}
2015-07-28 05:47:17 +00:00
: ( before " End Primitive Recipe Implementations " )
case _PRINT : {
2016-10-20 05:10:35 +00:00
for ( int i = 0 ; i < SIZE ( ingredients ) ; + + i ) {
2015-07-28 05:47:17 +00:00
if ( is_literal ( current_instruction ( ) . ingredients . at ( i ) ) ) {
2015-10-29 19:09:23 +00:00
trace ( 9998 , " run " ) < < " $print: " < < current_instruction ( ) . ingredients . at ( i ) . name < < end ( ) ;
2016-08-09 23:42:11 +00:00
if ( ! has_property ( current_instruction ( ) . ingredients . at ( i ) , " newline " ) ) {
2015-07-28 05:47:17 +00:00
cout < < current_instruction ( ) . ingredients . at ( i ) . name ;
2016-08-09 23:42:11 +00:00
}
// hack: '$print 10' prints '10', but '$print 10/newline' prints '\n'
// End $print 10/newline Special-cases
else {
cout < < ' \n ' ;
}
2015-07-28 05:47:17 +00:00
}
2016-11-12 09:05:38 +00:00
// End $print Special-cases
2015-07-28 05:47:17 +00:00
else {
2016-10-20 05:10:35 +00:00
for ( int j = 0 ; j < SIZE ( ingredients . at ( i ) ) ; + + j ) {
2015-10-29 19:09:23 +00:00
trace ( 9998 , " run " ) < < " $print: " < < ingredients . at ( i ) . at ( j ) < < end ( ) ;
2015-07-28 05:47:17 +00:00
if ( j > 0 ) cout < < " " ;
2015-09-15 06:30:03 +00:00
cout < < no_scientific ( ingredients . at ( i ) . at ( j ) ) ;
2015-07-28 05:47:17 +00:00
}
}
}
2015-11-15 20:35:59 +00:00
cout . flush ( ) ;
2015-07-28 05:47:17 +00:00
break ;
}
: ( before " End Primitive Recipe Declarations " )
_EXIT ,
: ( before " End Primitive Recipe Numbers " )
2015-11-06 19:06:58 +00:00
put ( Recipe_ordinal , " $exit " , _EXIT ) ;
2015-10-02 00:30:14 +00:00
: ( before " End Primitive Recipe Checks " )
case _EXIT : {
break ;
}
2015-07-28 05:47:17 +00:00
: ( before " End Primitive Recipe Implementations " )
case _EXIT : {
exit ( 0 ) ;
break ;
}
: ( before " End Primitive Recipe Declarations " )
_SYSTEM ,
: ( before " End Primitive Recipe Numbers " )
2015-11-06 19:06:58 +00:00
put ( Recipe_ordinal , " $system " , _SYSTEM ) ;
2015-10-01 07:13:45 +00:00
: ( before " End Primitive Recipe Checks " )
2015-07-28 05:47:17 +00:00
case _SYSTEM : {
2015-10-07 05:15:45 +00:00
if ( SIZE ( inst . ingredients ) ! = 1 ) {
2016-05-21 05:09:06 +00:00
raise < < maybe ( get ( Recipe , r ) . name ) < < " '$system' requires exactly one ingredient, but got ' " < < to_string ( inst ) < < " ' \n " < < end ( ) ;
2015-07-28 05:47:17 +00:00
break ;
}
2016-09-17 06:52:15 +00:00
if ( ! is_literal_text ( inst . ingredients . at ( 0 ) ) ) {
2016-05-21 05:09:06 +00:00
raise < < maybe ( get ( Recipe , r ) . name ) < < " ingredient to '$system' must be a literal text, but got ' " < < to_string ( inst ) < < " ' \n " < < end ( ) ;
2016-05-12 02:28:29 +00:00
}
2015-10-01 07:13:45 +00:00
break ;
}
: ( before " End Primitive Recipe Implementations " )
case _SYSTEM : {
2015-07-28 20:05:17 +00:00
int status = system ( current_instruction ( ) . ingredients . at ( 0 ) . name . c_str ( ) ) ;
2015-08-03 05:18:19 +00:00
products . resize ( 1 ) ;
2015-07-28 05:47:17 +00:00
products . at ( 0 ) . push_back ( status ) ;
break ;
}
: ( before " End Primitive Recipe Declarations " )
_DUMP_MEMORY ,
: ( before " End Primitive Recipe Numbers " )
2015-11-06 19:06:58 +00:00
put ( Recipe_ordinal , " $dump-memory " , _DUMP_MEMORY ) ;
2015-10-02 00:30:14 +00:00
: ( before " End Primitive Recipe Checks " )
case _DUMP_MEMORY : {
break ;
}
2015-07-28 05:47:17 +00:00
: ( before " End Primitive Recipe Implementations " )
case _DUMP_MEMORY : {
dump_memory ( ) ;
break ;
}
2015-12-14 09:30:56 +00:00
//: In times of real extremis we need to create a whole new modality for debug
//: logs, independent of other changes to the screen or Trace_stream.
: ( before " End Globals " )
ofstream LOG ;
: ( before " End One-time Setup " )
//? LOG.open("log");
: ( before " End Primitive Recipe Declarations " )
_LOG ,
: ( before " End Primitive Recipe Numbers " )
put ( Recipe_ordinal , " $log " , _LOG ) ;
: ( before " End Primitive Recipe Checks " )
case _LOG : {
break ;
}
: ( before " End Primitive Recipe Implementations " )
case _LOG : {
ostringstream out ;
2016-10-20 05:10:35 +00:00
for ( int i = 0 ; i < SIZE ( current_instruction ( ) . ingredients ) ; + + i ) {
2016-11-12 07:30:16 +00:00
out < < inspect ( current_instruction ( ) . ingredients . at ( i ) , ingredients . at ( i ) ) ;
2015-12-14 09:30:56 +00:00
}
2016-02-01 21:29:46 +00:00
LOG < < out . str ( ) < < ' \n ' ;
2015-12-14 09:30:56 +00:00
break ;
}
2016-04-21 03:07:50 +00:00
2016-10-22 23:56:07 +00:00
//: set a variable from within Mu code
2016-04-21 03:07:50 +00:00
//: useful for selectively tracing or printing after some point
: ( before " End Globals " )
bool Foo = false ;
: ( before " End Primitive Recipe Declarations " )
_FOO ,
: ( before " End Primitive Recipe Numbers " )
put ( Recipe_ordinal , " $foo " , _FOO ) ;
: ( before " End Primitive Recipe Checks " )
case _FOO : {
break ;
}
: ( before " End Primitive Recipe Implementations " )
case _FOO : {
Foo = true ;
break ;
}