/* gettok.c */
/* Copyright 1992 by P.J. LaBrocca */

#include <stdio.h>
#include <ctype.h>
#include "mixed.h"
#include "mixcalc.h"

#define LookAhead(x)  while( (x = getchar()) == ' ' || x == '\t' )

jmp_buf startup;

mixed_t *M;
enum token_value CurrentToken;

enum token_value  gettok( void ) {
    int c;
    Integer tmp1, tmp2, tmp3;

    LookAhead( c );
    if( c == EOF )
        return CurrentToken = ENDFILE;
    if( isdigit(c) ) {
        ungetc( c, stdin );
        scanf("%ld", &tmp1);
        LookAhead(c);
        if( isdigit(c) ) {
            ungetc( c, stdin );
            scanf("%ld", &tmp2);
            LookAhead(c);
			if( c != '|' ) {
				fprintf( stderr, "Expected '|'\n");
                fflush( stdin );
                longjmp( startup, 1 );
            }
            LookAhead(c);
            if( !isdigit(c) ) {
				fprintf( stderr, "Expected a digit\n");
                fflush( stdin );
                longjmp( startup, 1 );
            }
            ungetc( c, stdin );
            scanf("%ld", &tmp3 );
			if( tmp3 == 0 ) {
				fprintf( stderr, "Denominator cannot be zero\n");
                fflush( stdin );
                longjmp( startup, 1 );
            }
			mix_init( M, tmp1, tmp2, tmp3 );
            return CurrentToken = NUMBER;
        }
		if( c == '|') {
            LookAhead( c );
            if( !isdigit(c) ) {
				fprintf( stderr, "Expected a digit\n");
                fflush( stdin );
                longjmp( startup, 1 );
            }
            ungetc( c, stdin );
            scanf("%ld", &tmp2 );
			if( tmp2 == 0 ) {
				fprintf( stderr, "Denominator cannot be zero\n");
                fflush( stdin );
                longjmp( startup, 1 );
            }
			mix_init( M, 0, tmp1, tmp2 );
            return CurrentToken = NUMBER;
        }
        ungetc( c, stdin );
		mix_init( M, tmp1, 0, 1 );
        return CurrentToken = NUMBER;
    }
    if( c == '\n' || c == ';')
        return CurrentToken = PRINT;
    switch( c ) {
        case '*':
        case '+':
        case '-':
        case '/':
        case '(':
        case ')':
            return CurrentToken = c;
        default:
			fprintf( stderr, "Unknown token: %c\n", c);
            fflush( stdin );
            longjmp( startup, 1 );
    }
}

