%{
#undef YY_INPUT
#define YY_INPUT(buf, result, max_size) (result = my_yyinput(buf, max_size))
#include <stdio.h>
#include <string.h>
#include <readline/readline.h>
#include "DBG.h"
#include "calc.h"
#include "y.tab.h"
static int my_yyinput(char *buf, int max_size);
%}
%start COMMENT
%%
<INITIAL>"define" return DEFINE;
<INITIAL>"if" return IF;
<INITIAL>"else" return ELSE;
<INITIAL>"while" return WHILE;
<INITIAL>"(" return LP;
<INITIAL>")" return RP;
<INITIAL>"{" return LC;
<INITIAL>"}" return RC;
<INITIAL>";" return SEMICOLON;
<INITIAL>"," return COMMA;
<INITIAL>"=" return ASSIGN;
<INITIAL>"==" return EQ;
<INITIAL>"!=" return NE;
<INITIAL>">" return GT;
<INITIAL>">=" return GE;
<INITIAL>"<" return LT;
<INITIAL>"<=" return LE;
<INITIAL>"+" return ADD;
<INITIAL>"-" return SUB;
<INITIAL>"*" return MUL;
<INITIAL>"/" return DIV;
<INITIAL>"%" return MOD;
<INITIAL>[A-Za-z_][A-Za-z_0-9]* {
yylval.identifier = clc_malloc(strlen(yytext) + 1);
strcpy(yylval.identifier, yytext);
return IDENTIFIER;
}
<INITIAL>[1-9][0-9]* {
Expression *expression = clc_alloc_expression(INT_EXPRESSION);
sscanf(yytext, "%d", &expression->u.int_value);
yylval.expression = expression;
return INT_LITERAL;
}
<INITIAL>"0" {
Expression *expression = clc_alloc_expression(INT_EXPRESSION);
expression->u.int_value = 0;
yylval.expression = expression;
return INT_LITERAL;
}
<INITIAL>[0-9]*\.[0-9]* {
Expression *expression = clc_alloc_expression(DOUBLE_EXPRESSION);
sscanf(yytext, "%lf", &expression->u.double_value);
yylval.expression = expression;
return DOUBLE_LITERAL;
}
<INITIAL>[ \t\n] ;
<INITIAL>^# BEGIN COMMENT;
<INITIAL>. clc_compile_error(CHARACTER_INVALID_ERR, NULL);
<COMMENT>\n BEGIN INITIAL;
<COMMENT>. ;
%%
static char *st_readline_buffer;
static int st_readline_used_len;
void
clc_initialize_readline_buffer(void)
{
if (st_readline_buffer) {
free(st_readline_buffer);
}
st_readline_buffer = NULL;
st_readline_used_len = 0;
}
static int
tty_input(char *buf, int max_size)
{
int len;
if (st_readline_buffer == NULL) {
st_readline_used_len = 0;
st_readline_buffer = readline(">");
if (st_readline_buffer == NULL) {
return 0;
}
}
len = smaller(strlen(st_readline_buffer) - st_readline_used_len,
max_size);
strncpy(buf, &st_readline_buffer[st_readline_used_len], len);
st_readline_used_len += len;
if (st_readline_buffer[st_readline_used_len] == '\0') {
free(st_readline_buffer);
st_readline_buffer = NULL;
}
return len;
}
static int
file_input(char *buf, int max_size)
{
int ch;
int len;
if (feof(clc_current_interpreter->input_fp))
return 0;
for (len = 0; len < max_size; len++) {
ch = getc(clc_current_interpreter->input_fp);
if (ch == EOF)
break;
buf[len] = ch;
len++;
}
return len;
}
static int
my_yyinput(char *buf, int max_size)
{
int result;
switch (clc_current_interpreter->input_mode) {
case CLC_TTY_INPUT_MODE:
result = tty_input(buf, max_size);
break;
case CLC_FILE_INPUT_MODE:
result = file_input(buf, max_size);
break;
default:
DBG_assert(0, ("bad default(%d).\n",
clc_current_interpreter->input_mode));
}
return result;
}