diff --git a/Makefile b/Makefile index cabb741..043dc45 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC=gcc CFLAGS=-Wall -pedantic -g -DUNIX_HOST -LIBS=-lm +LIBS=-lm -lreadline TARGET = picoc SRCS = picoc.c table.c lex.c parse.c expression.c heap.c type.c \ diff --git a/clibrary.c b/clibrary.c index 4869807..ef6f5f2 100644 --- a/clibrary.c +++ b/clibrary.c @@ -327,7 +327,7 @@ void LibGets(struct ParseState *Parser, struct Value *ReturnValue, struct Value char *Result; ReturnValue->Val->Pointer = NULL; - Result = PlatformGetLine(ReadBuffer, GETS_BUF_MAX); + Result = PlatformGetLine(ReadBuffer, GETS_BUF_MAX, NULL); if (Result == NULL) return; diff --git a/lex.c b/lex.c index 2f955bd..2a494f1 100644 --- a/lex.c +++ b/lex.c @@ -556,6 +556,7 @@ enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int I { enum LexToken Token = TokenNone; int ValueSize; + char *Prompt = NULL; do { @@ -586,13 +587,13 @@ enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int I /* get interactive input */ if (LexUseStatementPrompt) { - PlatformPrintf(INTERACTIVE_PROMPT_STATEMENT); + Prompt = INTERACTIVE_PROMPT_STATEMENT; LexUseStatementPrompt = FALSE; } else - PlatformPrintf(INTERACTIVE_PROMPT_LINE); + Prompt = INTERACTIVE_PROMPT_LINE; - if (PlatformGetLine(&LineBuffer[0], LINEBUFFER_MAX) == NULL) + if (PlatformGetLine(&LineBuffer[0], LINEBUFFER_MAX, Prompt) == NULL) return TokenEOF; /* put the new line at the end of the linked list of interactive lines */ diff --git a/picoc.h b/picoc.h index e6dedc6..7a73b9a 100644 --- a/picoc.h +++ b/picoc.h @@ -398,7 +398,7 @@ void AssignFail(struct ParseState *Parser, const char *Format, struct ValueType void LexFail(struct LexState *Lexer, const char *Message, ...); void PlatformCleanup(); void PlatformScanFile(const char *FileName); -char *PlatformGetLine(char *Buf, int MaxLen); +char *PlatformGetLine(char *Buf, int MaxLen, const char *Prompt); int PlatformGetCharacter(); void PlatformPutc(unsigned char OutCh, union OutputStreamInfo *); void PlatformErrorPrefix(struct ParseState *Parser); diff --git a/platform.h b/platform.h index a517109..4310cd2 100644 --- a/platform.h +++ b/platform.h @@ -54,7 +54,7 @@ # ifndef NO_FP # include # define PICOC_MATH_LIBRARY -/*# define NEED_MATH_LIBRARY*/ +# define USE_READLINE # undef BIG_ENDIAN # if defined(__powerpc__) || defined(__hppa__) || defined(__sparc__) # define BIG_ENDIAN diff --git a/platform/platform_unix.c b/platform/platform_unix.c index e3775e6..50f6b57 100644 --- a/platform/platform_unix.c +++ b/platform/platform_unix.c @@ -1,5 +1,10 @@ #include "../picoc.h" +#ifdef USE_READLINE +#include +#include +#endif + /* a source file we need to clean up */ static char *CleanupText = NULL; @@ -11,8 +16,31 @@ void PlatformCleanup() } /* get a line of interactive input */ -char *PlatformGetLine(char *Buf, int MaxLen) +char *PlatformGetLine(char *Buf, int MaxLen, const char *Prompt) { +#ifdef USE_READLINE + if (Prompt != NULL) + { + /* use GNU readline to read the line */ + char *InLine = readline(Prompt); + if (InLine == NULL) + return NULL; + + Buf[MaxLen] = '\0'; + strncpy(Buf, InLine, MaxLen-1); + strncat(Buf, "\n", MaxLen-1); + + if (InLine[0] != '\0') + add_history(InLine); + + free(InLine); + return Buf; + } +#endif + + if (Prompt != NULL) + printf("%s", Prompt); + fflush(stdout); return fgets(Buf, MaxLen, stdin); }