Interactive mode now works.
git-svn-id: http://picoc.googlecode.com/svn/trunk@167 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
parent
2e0ff8774c
commit
46c4bad533
56
lex.c
56
lex.c
|
@ -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
14
parse.c
|
@ -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
14
picoc.c
|
@ -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
|
||||
|
|
2
picoc.h
2
picoc.h
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue