Skip to content

Instantly share code, notes, and snippets.

@theMackabu
Created September 10, 2026 00:00
Show Gist options
  • Select an option

  • Save theMackabu/c73f1f3c5d49c0b42e76ed247f9a72b8 to your computer and use it in GitHub Desktop.

Select an option

Save theMackabu/c73f1f3c5d49c0b42e76ed247f9a72b8 to your computer and use it in GitHub Desktop.
/* # 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