-
-
Save theMackabu/c73f1f3c5d49c0b42e76ed247f9a72b8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* # run this example using the program below | |
| n = 1; | |
| f = 1; | |
| while (n <= 7) { | |
| f = f * n; | |
| print f; | |
| n = n + 1; | |
| } | |
| if (f == 5040) print 1; else print 0; */ | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| static char src [ 65536 ] , * p = src ; static | |
| int t , n , a [ 26 ] ; static void die ( void | |
| ) { fputs ( "error\n" , stderr ) ; exit ( 1 ) ; | |
| } static void next ( void ) { char * q ; int | |
| k ; while ( * p && * p <= 32 ) ++ p ; if ( * p | |
| == '#' ) { while ( * p && * p != '\n' ) ++ p ; | |
| next ( ) ; return ; } t = ( unsigned char ) * p | |
| ; if ( ! t ) return ; ++ p ; if ( t >= '0' && | |
| t <= '9' ) { n = ( int ) strtol ( p - 1 , & p , | |
| 10 ) ; t = 'V' ; } else if ( t >= 'a' && t <= 'z' | |
| ) { q = p - 1 ; while ( * p >= 'a' && * p <= 'z' ) | |
| ++ p ; k = ( int ) ( p - q ) ; if ( k == 1 ) { n = * q | |
| - 'a' ; t = 'A' ; } else if ( k == 2 && ! memcmp ( q , | |
| "if" , 2 ) ) t = 'I' ; else if ( k == 4 && ! memcmp ( q , | |
| "else" , 4 ) ) t = 'E' ; else if ( k == 5 && ! memcmp ( q , | |
| "while" , 5 ) ) t = 'W' ; else if ( k == 5 && ! memcmp ( q , | |
| "print" , 5 ) ) t = 'P' ; else die ( ) ; } else if ( * p == '=' | |
| && ( t == '=' || t == '!' || t == '<' || t == '>' ) ) { ++ p ; t = | |
| t == '=' ? 'Q' : t == '!' ? 'N' : t == '<' ? 'L' : 'G' ; } else if ( | |
| ( t == '&' || t == '|' ) && * p == t ) ++ p ; else if ( t == '&' || t | |
| == '|' || ! strchr ( "+-*/%<>=!(){};" , t ) ) die ( ) ; } | |
| static void need ( int c ) { if ( t != c ) die ( ) ; next ( ) ; } static | |
| int prec ( void ) { if ( ! t ) return 0 ; return t == '|' ? 1 : t == '&' ? 2 | |
| : strchr ( "QN" , t ) ? 3 : strchr ( "<>LG" , t ) ? 4 : strchr ( "+-" , t ) | |
| ? 5 : strchr ( "*/%" , t ) ? 6 : 0 ; } static int expr ( int m , int run ) { | |
| int x , y , o , k ; if ( t == '+' || t == '-' || t == '!' ) { o = t ; next ( | |
| ) ; x = expr ( 7 , run ) ; if ( run ) x = o == '-' ? - x : o == '!' ? ! x : x ; | |
| } else if ( t == '(' ) { next ( ) ; x = expr ( 1 , run ) ; need ( ')' ) ; } else | |
| if ( t == 'V' || t == 'A' ) { x = t == 'V' ? n : a [ n ] ; next ( ) ; } else { | |
| die ( ) ; return 0 ; } while ( ( k = prec ( ) ) >= m ) { o = t ; next ( ) ; | |
| y = expr ( k + 1 , run && ! ( o == '&' && ! x ) && ! ( o == '|' && x ) ) ; if | |
| ( run ) { if ( ( o == '/' || o == '%' ) && ! y ) die ( ) ; x = o == '+' ? x + | |
| y : o == '-' ? x - y : o == '*' ? x * y : o == '/' ? x / y : o == '%' ? x % y : | |
| o == '<' ? x < y : o == '>' ? x > y : o == 'L' ? x <= y : o == 'G' ? x >= y : o | |
| == 'Q' ? x == y : o == 'N' ? x != y : o == '&' ? x && y : x || y ; } } return x | |
| ; } static void stmt ( int run ) { int c , v ; char * q ; if ( t == '{' ) { | |
| next ( ) ; while ( t && t != '}' ) stmt ( run ) ; need ( '}' ) ; } else if ( t | |
| == 'I' ) { next ( ) ; need ( '(' ) ; c = expr | |
| ( 1 , run ) ; need ( ')' ) ; stmt ( run && c | |
| ) ; if ( t == 'E' ) { next ( ) ; stmt ( run | |
| && ! c ) ; } } else if ( t == 'W' ) { q = p ; | |
| do { p = q ; next ( ) ; need ( '(' ) ; c = expr | |
| ( 1 , run ) ; need ( ')' ) ; stmt ( run && c | |
| ) ; } while ( run && c ) ; } else if ( t == | |
| 'P' ) { next ( ) ; v = expr ( 1 , run ) ; need | |
| ( ';' ) ; if ( run ) printf ( "%d\n" , v ) ; | |
| } else if ( t == 'A' ) { c = n ; next ( ) ; | |
| need ( '=' ) ; v = expr ( 1 , run ) ; need ( | |
| ';' ) ; if ( run ) a [ c ] = v ; } else need ( | |
| ';' ) ; } int main ( int argc , char * * | |
| argv ) { FILE * f = stdin ; size_t len ; if | |
| ( argc > 2 ) die ( ) ; if ( argc == 2 ) { f = | |
| fopen ( argv [ 1 ] , "rb" ) ; if ( ! f ) die | |
| ( ) ; } len = fread ( src , 1 , sizeof ( src | |
| ) - 1 , f ) ; if ( ferror ( f ) || fgetc ( | |
| f ) != EOF || memchr ( src , 0 , len ) ) die ( | |
| ) ; if ( f != stdin ) fclose ( f ) ; next ( ) | |
| ; while ( t ) stmt ( 1 ) ; return 0 ; } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment