Interactive mode now works.

git-svn-id: http://picoc.googlecode.com/svn/trunk@167 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-03-08 04:26:28 +00:00
parent 2e0ff8774c
commit 46c4bad533
6 changed files with 85 additions and 20 deletions

56
lex.c
View file

@ -72,9 +72,10 @@ struct TokenLine
int NumBytes;
};
struct TokenLine *InteractiveHead = NULL;
struct TokenLine *InteractiveTail = NULL;
struct TokenLine *InteractiveCurrentLine = NULL;
static struct TokenLine *InteractiveHead = NULL;
static struct TokenLine *InteractiveTail = NULL;
static struct TokenLine *InteractiveCurrentLine = NULL;
static int LexUseStatementPrompt = FALSE;
/* initialise the lexer */
@ -466,6 +467,9 @@ enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int I
do
{ /* get the next token */
if (Parser->Pos == NULL && InteractiveHead != NULL)
Parser->Pos = InteractiveHead->Tokens;
if (Parser->FileName != StrEmpty || InteractiveHead != NULL)
{ /* skip leading newlines */
while ((Token = (enum LexToken)*(unsigned char *)Parser->Pos) == TokenEndOfLine)
@ -484,10 +488,13 @@ enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int I
if (InteractiveHead == NULL || (unsigned char *)Parser->Pos == &InteractiveTail->Tokens[InteractiveTail->NumBytes-1])
{ /* get interactive input */
if (InteractiveHead == NULL)
PlatformPrintf("picoc> ");
if (LexUseStatementPrompt)
{
PlatformPrintf(INTERACTIVE_PROMPT_STATEMENT);
LexUseStatementPrompt = FALSE;
}
else
PlatformPrintf("> ");
PlatformPrintf(INTERACTIVE_PROMPT_LINE);
if (PlatformGetLine(&LineBuffer[0], LINEBUFFER_MAX) == NULL)
return TokenEOF;
@ -631,8 +638,43 @@ void *LexCopyTokens(struct ParseState *StartParser, struct ParseState *EndParser
return NewTokens;
}
/* indicate that we've completed up to this point in the interactive input and free expired tokens */
void LexInteractiveClear(struct ParseState *Parser)
{
while (InteractiveHead != NULL)
{
struct TokenLine *NextLine = InteractiveHead->Next;
HeapFree(InteractiveHead->Tokens);
HeapFree(InteractiveHead);
InteractiveHead = NextLine;
}
Parser->Pos = NULL;
InteractiveTail = NULL;
}
/* indicate that we've completed up to this point in the interactive input and free expired tokens */
void LexInteractiveCompleted(struct ParseState *Parser)
{
//XXX - write this
while (InteractiveHead != NULL && !(Parser->Pos >= (void *)&InteractiveHead->Tokens[0] && Parser->Pos < (void *)&InteractiveHead->Tokens[InteractiveHead->NumBytes]))
{ /* this token line is no longer needed - free it */
struct TokenLine *NextLine = InteractiveHead->Next;
HeapFree(InteractiveHead->Tokens);
HeapFree(InteractiveHead);
InteractiveHead = NextLine;
if (InteractiveHead == NULL)
{ /* we've emptied the list */
Parser->Pos = NULL;
InteractiveTail = NULL;
}
}
}
/* the next time we prompt, make it the full statement prompt */
void LexInteractiveStatementPrompt()
{
LexUseStatementPrompt = TRUE;
}

14
parse.c
View file

@ -1075,9 +1075,19 @@ void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt)
void ParseInteractive()
{
struct ParseState Parser;
int Ok;
LexInitParser(&Parser, NULL, StrEmpty, 1, TRUE);
while (ParseStatement(&Parser))
PlatformSetExitPoint();
LexInteractiveClear(&Parser);
do
{
LexInteractiveStatementPrompt();
Ok = ParseStatement(&Parser);
LexInteractiveCompleted(&Parser);
} while (Ok);
PlatformPrintf("\n");
}

14
picoc.c
View file

@ -18,17 +18,23 @@ void Initialise()
int main(int argc, char **argv)
{
if (argc < 2)
ProgramFail(NULL, "Format: picoc <program.c> - run a program\n picoc -i - interactive mode\n");
{
PlatformPrintf("Format: picoc <program.c> - run a program\n picoc -i - interactive mode\n");
exit(1);
}
Initialise();
if (PlatformSetExitPoint())
return 1;
if (strcmp(argv[1], "-i") == 0)
ParseInteractive();
else
{
if (PlatformSetExitPoint())
return 1;
PlatformScanFile(argv[1]);
}
return 0;
}
#else

View file

@ -260,7 +260,9 @@ void LexInitParser(struct ParseState *Parser, void *TokenSource, const char *Fil
enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int IncPos);
void LexToEndOfLine(struct ParseState *Parser);
void *LexCopyTokens(struct ParseState *StartParser, struct ParseState *EndParser);
void LexInteractiveClear(struct ParseState *Parser);
void LexInteractiveCompleted(struct ParseState *Parser);
void LexInteractiveStatementPrompt();
/* parse.c */
int ParseExpression(struct ParseState *Parser, struct Value **Result);

View file

@ -20,6 +20,9 @@
#define LOCAL_TABLE_SIZE 11 /* size of local variable table (can expand) */
#define STRUCT_TABLE_SIZE 11 /* size of struct/union member table (can expand) */
#define INTERACTIVE_PROMPT_STATEMENT "picoc> "
#define INTERACTIVE_PROMPT_LINE "> "
/* host platform includes */
#ifdef UNIX_HOST
#include <stdio.h>
@ -31,6 +34,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <stdarg.h>
#include <setjmp.h>
#ifndef NO_FP
#include <math.h>
#endif

View file

@ -51,15 +51,16 @@ void PlatformScanFile(const char *FileName)
}
/* mark where to end the program for platforms which require this */
static jmp_buf ExitBuf;
int PlatformSetExitPoint()
{
return 0;
return setjmp(ExitBuf);
}
/* exit the program */
void PlatformExit()
{
exit(1);
longjmp(ExitBuf, 1);
}
#endif
@ -67,19 +68,19 @@ void PlatformExit()
/* get a line of interactive input */
char *PlatformGetLine(char *Buf, int MaxLen)
{
return NULL;
return NULL;
}
/* write a character to the console */
void PlatformPutc(unsigned char OutCh)
{
putchar(OutCh);
putchar(OutCh);
}
/* mark where to end the program for platforms which require this */
int PlatformSetExitPoint()
{
return 0;
return 0;
}
/* exit the program */
@ -87,8 +88,8 @@ extern int errjmp[];
void PlatformExit()
{
errjmp[40] = 1;
longjmp(errjmp, 1);
errjmp[40] = 1;
longjmp(errjmp, 1);
}
#endif