Skip to content

Commit

Permalink
Big reorganisation to make it easier to port to different targets
Browse files Browse the repository at this point in the history
  • Loading branch information
zik.saleeba committed Feb 24, 2009
1 parent 6fcd7f5 commit d8b4458
Show file tree
Hide file tree
Showing 12 changed files with 256 additions and 150 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
CC=gcc
CFLAGS=-Wall -g #-DNO_FP #-DDEBUG_LEXER #-DDEBUG_HEAP
CFLAGS=-Wall -g
LIBS=-lm

TARGET = picoc
SRCS = picoc.c table.c lex.c parse.c intrinsic.c heap.c type.c variable.c
SRCS = picoc.c table.c lex.c parse.c heap.c type.c variable.c clibrary.c platform_library.c platform_support.c
OBJS := $(SRCS:%.c=%.o)

all: $(TARGET)
Expand Down
1 change: 1 addition & 0 deletions TODO
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ TODO
* change heap to use a single consistent freelist node struct
* periodic heap cleanup
* fix type comparison to take into account array size
* fix return of array types
* expression and auto-cast support for all types
* octal/hex character constants
* fix #include
Expand Down
59 changes: 34 additions & 25 deletions intrinsic.c → clibrary.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "picoc.h"

/* initialise a library */
void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct IntrinsicFunction *FuncList[])
void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction (*FuncList)[])
{
struct ParseState Parser;
int Count;
Expand All @@ -11,32 +11,39 @@ void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct Intr
void *Tokens;
const char *IntrinsicName = TableStrRegister("c library");

for (Count = 0; Count < sizeof(Intrinsics) / sizeof(struct IntrinsicFunction); Count++)
for (Count = 0; (*FuncList)[Count].Prototype != NULL; Count++)
{
Tokens = LexAnalyse(IntrinsicName, Intrinsics[Count].Prototype, strlen(Intrinsics[Count].Prototype));
Tokens = LexAnalyse(IntrinsicName, (*FuncList)[Count].Prototype, strlen((*FuncList)[Count].Prototype));
LexInitParser(&Parser, Tokens, IntrinsicName, Count+1, TRUE);
TypeParse(&Parser, &ReturnType, &Identifier);
NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier, TRUE);
NewValue->Val->FuncDef.Intrinsic = Intrinsics[Count].Func;
NewValue->Val->FuncDef.Intrinsic = (*FuncList)[Count].Func;
HeapFree(Tokens);
}
}

/* print a string to a stream without using printf/sprintf */
void PrintStr(const char *Str, CharWriter *PutCh)
{
while (*Str != 0)
PutCh(*Str++);
}

/* print an integer to a stream without using printf/sprintf */
void PrintInt(int Num, FILE *Stream)
void PrintInt(int Num, CharWriter *PutCh)
{
int Div;
int Remainder = 0;
int Printing = FALSE;

if (Num < 0)
{
fputc('-', Stream);
PutCh('-');
Num = -Num;
}

if (Num == 0)
fputc('0', Stream);
PutCh('0');
else
{
Div = LARGE_INT_POWER_OF_TEN;
Expand All @@ -45,7 +52,7 @@ void PrintInt(int Num, FILE *Stream)
Remainder = Num / Div;
if (Printing || Remainder > 0)
{
fputc('0' + Remainder, Stream);
PutCh('0' + Remainder);
Printing = TRUE;
}
Num -= Remainder * Div;
Expand All @@ -56,7 +63,7 @@ void PrintInt(int Num, FILE *Stream)

#ifndef NO_FP
/* print a double to a stream without using printf/sprintf */
void PrintFP(double Num, FILE *Stream)
void PrintFP(double Num, CharWriter *PutCh)
{
int Exponent = 0;

Expand All @@ -66,15 +73,15 @@ void PrintFP(double Num, FILE *Stream)
Exponent = log(Num) / LOG10E - 0.999999999;

Num /= pow(10.0, Exponent);
PrintInt((int)Num, Stream);
fputc('.', Stream);
PrintInt((int)Num, PutCh);
PutCh('.');
for (Num -= (int)Num; Num != 0.0; Num *= 10.0)
fputc('0' + (int)Num, Stream);
PutCh('0' + (int)Num);

if (Exponent)
{
fputc('e', Stream);
PrintInt(Exponent, Stream);
PutCh('e');
PrintInt(Exponent, PutCh);
}
}
#endif
Expand Down Expand Up @@ -106,20 +113,20 @@ void LibPrintf(struct Value *ReturnValue, struct Value **Param, int NumArgs)
#ifndef NO_FP
case 'f': FormatType = &FPType; break;
#endif
case '%': fputc('%', stdout); FormatType = NULL; break;
case '%': PlatformPutc('%'); FormatType = NULL; break;
case '\0': FPos--; FormatType = NULL; break;
default: putchar(*FPos); FormatType = NULL; break;
default: PlatformPutc(*FPos); FormatType = NULL; break;
}

if (FormatType != NULL)
{ /* we have to format something */
if (ArgCount >= NumArgs)
fputs("XXX", stdout); /* not enough parameters for format */
PrintStr("XXX", PlatformPutc); /* not enough parameters for format */
else
{
NextArg = (struct Value *)((void *)NextArg + sizeof(struct Value) + TypeSizeValue(NextArg));
if (NextArg->Typ != FormatType)
fputs("XXX", stdout); /* bad type for format */
PrintStr("XXX", PlatformPutc); /* bad type for format */
else
{
switch (*FPos)
Expand All @@ -134,13 +141,13 @@ void LibPrintf(struct Value *ReturnValue, struct Value **Param, int NumArgs)
else
Str = CharArray->Val->Array.Data + NextArg->Val->Pointer.Data.Offset;

fputs(Str, stdout);
PrintStr(Str, PlatformPutc);
break;
}
case 'd': PrintInt(NextArg->Val->Integer, stdout); break;
case 'c': fputc(NextArg->Val->Integer, stdout); break;
case 'd': PrintInt(NextArg->Val->Integer, PlatformPutc); break;
case 'c': PlatformPutc(NextArg->Val->Integer); break;
#ifndef NO_FP
case 'f': PrintFP(NextArg->Val->FP, stdout); break;
case 'f': PrintFP(NextArg->Val->FP, PlatformPutc); break;
#endif
}
}
Expand All @@ -150,11 +157,13 @@ void LibPrintf(struct Value *ReturnValue, struct Value **Param, int NumArgs)
}
}
else
putchar(*FPos);
PlatformPutc(*FPos);
}
}

struct IntrinsicFunction CLibrary[] =
/* list of all library functions and their prototypes */
struct LibraryFunction CLibrary[] =
{
{ LibPrintf, "void printf(char *, ...)" },
{ LibPrintf, "void printf(char *, ...)" },
{ NULL, NULL }
};
3 changes: 0 additions & 3 deletions heap.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
/* stack grows up from the bottom and heap grows down from the top of heap space */
#include <stdio.h>
#include <memory.h>
#include <assert.h>
#include "picoc.h"

#define FREELIST_BUCKETS 8 /* freelists for 4, 8, 12 ... 32 byte allocs */
Expand Down
15 changes: 5 additions & 10 deletions lex.c
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <stdarg.h>

#include "picoc.h"

#ifndef isalpha
#ifdef NO_CTYPE
#define isalpha(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
#define isalnum(c) (isalpha(c) || ((c) >= '0' && (c) <= '9'))
#define isdigit(c) ((c) >= '0' && (c) <= '9')
#define isalnum(c) (isalpha(c) || isdigit(c))
#define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')
#endif
#define isCidstart(c) (isalpha(c) || (c)=='_' || (c)=='#')
#define isCident(c) (isalnum(c) || (c)=='_')
Expand Down Expand Up @@ -286,7 +281,7 @@ enum LexToken LexScanGetToken(struct LexState *Lexer, struct Value **Value)
if (Lexer->FileName == StrEmpty)
{ /* get interactive input */
char LineBuffer[LINEBUFFER_MAX];
if (fgets(&LineBuffer[0], LINEBUFFER_MAX, stdin) == NULL)
if (PlatformGetLine(&LineBuffer[0], LINEBUFFER_MAX) == NULL)
return TokenEOF;

// XXX - finish this
Expand Down
6 changes: 0 additions & 6 deletions parse.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#include <stdio.h>
#include <string.h>

#include "picoc.h"

/* local prototypes */
Expand All @@ -11,9 +8,6 @@ int ParseStatementMaybeRun(struct ParseState *Parser, int Condition);
/* initialise the parser */
void ParseInit()
{
VariableInit();
TypeInit();
IntrinsicInit(&GlobalTable);
}

/* do a function call */
Expand Down
105 changes: 31 additions & 74 deletions picoc.c
Original file line number Diff line number Diff line change
@@ -1,87 +1,44 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include "picoc.h"

/* all platform-dependent code is in this file */

void ProgramFail(struct ParseState *Parser, const char *Message, ...)
{
va_list Args;

if (Parser != NULL)
IntrinsicHostPrintf("%s:%d: ", Parser->FileName, Parser->Line);

va_start(Args, Message);
IntrinsicHostVPrintf(Message, Args);
IntrinsicHostPrintf("\n");
exit(1);
}

/* exit with a message */
void LexFail(struct LexState *Lexer, const char *Message, ...)
{
va_list Args;

IntrinsicHostPrintf("%s:%d: ", Lexer->FileName, Lexer->Line);
va_start(Args, Message);
IntrinsicHostVPrintf(Message, Args);
IntrinsicHostPrintf("\n");
exit(1);
}

/* read a file into memory */
char *ReadFile(const char *FileName)
{
struct stat FileInfo;
char *ReadText;
FILE *InFile;

if (stat(FileName, &FileInfo))
ProgramFail(NULL, "can't read file %s\n", FileName);

ReadText = malloc(FileInfo.st_size + 1);
if (ReadText == NULL)
ProgramFail(NULL, "out of memory\n");

InFile = fopen(FileName, "r");
if (InFile == NULL)
ProgramFail(NULL, "can't read file %s\n", FileName);

if (fread(ReadText, 1, FileInfo.st_size, InFile) != FileInfo.st_size)
ProgramFail(NULL, "can't read file %s\n", FileName);

ReadText[FileInfo.st_size] = '\0';
fclose(InFile);

return ReadText;
}

/* read and scan a file for definitions */
void ScanFile(const char *FileName)
/* initialise everything */
void Initialise()
{
char *SourceStr = ReadFile(FileName);
Parse(FileName, SourceStr, strlen(SourceStr), TRUE);
free(SourceStr);
HeapInit();
TableInit();
VariableInit();
LexInit();
VariableInit();
TypeInit();
LibraryInit(&GlobalTable, "c library", &CLibrary);
LibraryInit(&GlobalTable, "platform library", &PlatformLibrary);
ParseInit();
}

/* platform-dependent code for running programs is in this file */
#ifdef UNIX_HOST
int main(int argc, char **argv)
{
if (argc < 2)
ProgramFail(NULL, "Format: picoc <program.c> <args>...\n");

HeapInit();
TableInit();
VariableInit();
LexInit();
ParseInit();

ScanFile(argv[1]);
Initialise();
PlatformScanFile(argv[1]);

return 0;
}
#else
# ifdef SURVEYOR_HOST
static char *SourceStr = "\
printf(\"This is a test program\n\");\
for (Count = 1; Count <= 10; Count++)\
printf(\"%d\n\");\
";

int main(int argc, char **argv)
{
Initialise();
Parse("test.c", SourceStr, strlen(SourceStr), TRUE);
return 0;
}
# endif
#endif
Loading

0 comments on commit d8b4458

Please sign in to comment.