From b23d1e8e065a105e3741a642680768042b061fcc Mon Sep 17 00:00:00 2001 From: "zik.saleeba" Date: Thu, 17 Feb 2011 07:11:20 +0000 Subject: [PATCH] Big reorganisation to make it easier to access picoc as a library. Also moved most internal header stuff to the new header interpreter.h. git-svn-id: http://picoc.googlecode.com/svn/trunk@549 21eae674-98b7-11dd-bd71-f92a316d2d60 --- clibrary.c | 1 + cstdlib/ctype.c | 2 +- cstdlib/errno.c | 2 +- cstdlib/math.c | 2 +- cstdlib/stdbool.c | 2 +- cstdlib/stdio.c | 2 +- cstdlib/stdlib.c | 2 +- cstdlib/string.c | 2 +- cstdlib/time.c | 2 +- cstdlib/unistd.c | 2 +- expression.c | 2 +- heap.c | 2 +- include.c | 7 +- interpreter.h | 494 +++++++++++++++++++++++++++++++++++ lex.c | 2 +- parse.c | 7 +- picoc.c | 119 ++------- picoc.h | 481 +--------------------------------- platform.c | 84 +++++- platform.h | 8 - platform/library_ffox.c | 2 +- platform/library_srv1.c | 14 +- platform/library_surveyor.c | 2 +- platform/library_unix.c | 2 +- platform/platform_ffox.c | 2 +- platform/platform_surveyor.c | 2 +- platform/platform_unix.c | 13 +- table.c | 2 +- type.c | 2 +- variable.c | 2 +- 30 files changed, 659 insertions(+), 609 deletions(-) create mode 100644 interpreter.h diff --git a/clibrary.c b/clibrary.c index 88a073e..f4eb64b 100644 --- a/clibrary.c +++ b/clibrary.c @@ -1,4 +1,5 @@ #include "picoc.h" +#include "interpreter.h" /* the picoc version string */ static const char *VersionString = NULL; diff --git a/cstdlib/ctype.c b/cstdlib/ctype.c index 08662fe..d1e8140 100644 --- a/cstdlib/ctype.c +++ b/cstdlib/ctype.c @@ -1,6 +1,6 @@ /* string.h library for large systems - small embedded systems use clibrary.c instead */ #include -#include "../picoc.h" +#include "../interpreter.h" #ifndef BUILTIN_MINI_STDLIB diff --git a/cstdlib/errno.c b/cstdlib/errno.c index 071f7eb..e5becbf 100644 --- a/cstdlib/errno.c +++ b/cstdlib/errno.c @@ -1,6 +1,6 @@ /* string.h library for large systems - small embedded systems use clibrary.c instead */ #include -#include "../picoc.h" +#include "../interpreter.h" #ifndef BUILTIN_MINI_STDLIB diff --git a/cstdlib/math.c b/cstdlib/math.c index 83d5bdb..0ba29a4 100644 --- a/cstdlib/math.c +++ b/cstdlib/math.c @@ -1,5 +1,5 @@ /* stdio.h library for large systems - small embedded systems use clibrary.c instead */ -#include "../picoc.h" +#include "../interpreter.h" #ifndef BUILTIN_MINI_STDLIB #ifndef NO_FP diff --git a/cstdlib/stdbool.c b/cstdlib/stdbool.c index 80fc915..30b2528 100644 --- a/cstdlib/stdbool.c +++ b/cstdlib/stdbool.c @@ -1,5 +1,5 @@ /* string.h library for large systems - small embedded systems use clibrary.c instead */ -#include "../picoc.h" +#include "../interpreter.h" #ifndef BUILTIN_MINI_STDLIB diff --git a/cstdlib/stdio.c b/cstdlib/stdio.c index bd8ed0e..0bbafaf 100644 --- a/cstdlib/stdio.c +++ b/cstdlib/stdio.c @@ -1,6 +1,6 @@ /* stdio.h library for large systems - small embedded systems use clibrary.c instead */ #include -#include "../picoc.h" +#include "../interpreter.h" #ifndef BUILTIN_MINI_STDLIB diff --git a/cstdlib/stdlib.c b/cstdlib/stdlib.c index c280769..8eebb1c 100644 --- a/cstdlib/stdlib.c +++ b/cstdlib/stdlib.c @@ -1,5 +1,5 @@ /* stdlib.h library for large systems - small embedded systems use clibrary.c instead */ -#include "../picoc.h" +#include "../interpreter.h" #ifndef BUILTIN_MINI_STDLIB diff --git a/cstdlib/string.c b/cstdlib/string.c index 8ce8fb0..88f349f 100644 --- a/cstdlib/string.c +++ b/cstdlib/string.c @@ -1,5 +1,5 @@ /* string.h library for large systems - small embedded systems use clibrary.c instead */ -#include "../picoc.h" +#include "../interpreter.h" #ifndef BUILTIN_MINI_STDLIB diff --git a/cstdlib/time.c b/cstdlib/time.c index f66e39a..0406679 100644 --- a/cstdlib/time.c +++ b/cstdlib/time.c @@ -1,6 +1,6 @@ /* string.h library for large systems - small embedded systems use clibrary.c instead */ #include -#include "../picoc.h" +#include "../interpreter.h" #ifndef BUILTIN_MINI_STDLIB diff --git a/cstdlib/unistd.c b/cstdlib/unistd.c index 33b0076..a8dfa37 100644 --- a/cstdlib/unistd.c +++ b/cstdlib/unistd.c @@ -2,7 +2,7 @@ #include #include #include -#include "../picoc.h" +#include "../interpreter.h" #ifndef BUILTIN_MINI_STDLIB diff --git a/expression.c b/expression.c index bff30a2..7ee8f3a 100644 --- a/expression.c +++ b/expression.c @@ -1,4 +1,4 @@ -#include "picoc.h" +#include "interpreter.h" /* whether evaluation is left to right for a given precedence level */ diff --git a/heap.c b/heap.c index a0a4b24..926edad 100644 --- a/heap.c +++ b/heap.c @@ -1,5 +1,5 @@ /* stack grows up from the bottom and heap grows down from the top of heap space */ -#include "picoc.h" +#include "interpreter.h" #define FREELIST_BUCKETS 8 /* freelists for 4, 8, 12 ... 32 byte allocs */ #define SPLIT_MEM_THRESHOLD 16 /* don't split memory which is close in size */ diff --git a/include.c b/include.c index f9c1293..360fe93 100644 --- a/include.c +++ b/include.c @@ -1,4 +1,5 @@ #include "picoc.h" +#include "interpreter.h" #ifndef NO_HASH_INCLUDE @@ -62,7 +63,7 @@ void IncludeRegister(const char *IncludeName, void (*SetupFunction)(void), struc } /* include all of the system headers */ -void IncludeAllSystemHeaders() +void PicocIncludeAllSystemHeaders() { struct IncludeLibrary *ThisInclude = IncludeLibList; @@ -91,7 +92,7 @@ void IncludeFile(char *FileName) /* parse the setup C source code - may define types etc. */ if (LInclude->SetupCSource != NULL) - Parse(FileName, LInclude->SetupCSource, strlen(LInclude->SetupCSource), TRUE, TRUE, FALSE); + PicocParse(FileName, LInclude->SetupCSource, strlen(LInclude->SetupCSource), TRUE, TRUE, FALSE); /* set up the library functions */ if (LInclude->FuncList != NULL) @@ -103,7 +104,7 @@ void IncludeFile(char *FileName) } /* not a predefined file, read a real file */ - PlatformScanFile(FileName); + PicocPlatformScanFile(FileName); } #endif /* NO_HASH_INCLUDE */ diff --git a/interpreter.h b/interpreter.h new file mode 100644 index 0000000..0fac411 --- /dev/null +++ b/interpreter.h @@ -0,0 +1,494 @@ +#ifndef INTERPRETER_H +#define INTERPRETER_H + +#include "platform.h" + + +/* handy definitions */ +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef min +#define min(x,y) (((x)<(y))?(x):(y)) +#endif + +#define MEM_ALIGN(x) (((x) + sizeof(ALIGN_TYPE) - 1) & ~(sizeof(ALIGN_TYPE)-1)) + +#define GETS_BUF_MAX 256 + +/* small processors use a simplified FILE * for stdio, otherwise use the system FILE * */ +#ifdef BUILTIN_MINI_STDLIB +typedef struct OutputStream IOFILE; +#else +typedef FILE IOFILE; +#endif + +/* coercion of numeric types to other numeric types */ +#ifndef NO_FP +#define IS_FP(v) ((v)->Typ->Base == TypeFP) +#define FP_VAL(v) ((v)->Val->FP) +#else +#define IS_FP(v) 0 +#define FP_VAL(v) 0 +#endif + +#define IS_POINTER_COERCIBLE(v, ap) ((ap) ? ((v)->Typ->Base == TypePointer) : 0) +#define POINTER_COERCE(v) ((int)(v)->Val->Pointer) + +#define IS_INTEGER_NUMERIC_TYPE(t) ((t)->Base >= TypeInt && (t)->Base <= TypeUnsignedLong) +#define IS_INTEGER_NUMERIC(v) IS_INTEGER_NUMERIC_TYPE((v)->Typ) +#define IS_NUMERIC_COERCIBLE(v) (IS_INTEGER_NUMERIC(v) || IS_FP(v)) +#define IS_NUMERIC_COERCIBLE_PLUS_POINTERS(v,ap) (IS_NUMERIC_COERCIBLE(v) || IS_POINTER_COERCIBLE(v,ap)) + + +struct Table; + +/* lexical tokens */ +enum LexToken +{ + /* 0x00 */ TokenNone, + /* 0x01 */ TokenComma, + /* 0x02 */ TokenAssign, TokenAddAssign, TokenSubtractAssign, TokenMultiplyAssign, TokenDivideAssign, TokenModulusAssign, + /* 0x08 */ TokenShiftLeftAssign, TokenShiftRightAssign, TokenArithmeticAndAssign, TokenArithmeticOrAssign, TokenArithmeticExorAssign, + /* 0x0d */ TokenQuestionMark, TokenColon, + /* 0x0f */ TokenLogicalOr, + /* 0x10 */ TokenLogicalAnd, + /* 0x11 */ TokenArithmeticOr, + /* 0x12 */ TokenArithmeticExor, + /* 0x13 */ TokenAmpersand, + /* 0x14 */ TokenEqual, TokenNotEqual, + /* 0x16 */ TokenLessThan, TokenGreaterThan, TokenLessEqual, TokenGreaterEqual, + /* 0x1a */ TokenShiftLeft, TokenShiftRight, + /* 0x1c */ TokenPlus, TokenMinus, + /* 0x1e */ TokenAsterisk, TokenSlash, TokenModulus, + /* 0x21 */ TokenIncrement, TokenDecrement, TokenUnaryNot, TokenUnaryExor, TokenSizeof, TokenCast, + /* 0x27 */ TokenLeftSquareBracket, TokenRightSquareBracket, TokenDot, TokenArrow, + /* 0x2b */ TokenOpenBracket, TokenCloseBracket, + /* 0x2d */ TokenIdentifier, TokenIntegerConstant, TokenFPConstant, TokenStringConstant, TokenCharacterConstant, + /* 0x32 */ TokenSemicolon, TokenEllipsis, + /* 0x34 */ TokenLeftBrace, TokenRightBrace, + /* 0x36 */ TokenIntType, TokenCharType, TokenFloatType, TokenDoubleType, TokenVoidType, TokenEnumType, + /* 0x3c */ TokenLongType, TokenSignedType, TokenShortType, TokenStaticType, TokenAutoType, TokenRegisterType, TokenExternType, TokenStructType, TokenUnionType, TokenUnsignedType, TokenTypedef, + /* 0x46 */ TokenContinue, TokenDo, TokenElse, TokenFor, TokenIf, TokenWhile, TokenBreak, TokenSwitch, TokenCase, TokenDefault, TokenReturn, + /* 0x51 */ TokenHashDefine, TokenHashInclude, TokenHashIf, TokenHashIfdef, TokenHashIfndef, TokenHashElse, TokenHashEndif, + /* 0x58 */ TokenNew, TokenDelete, + /* 0x5a */ TokenOpenMacroBracket, + /* 0x5b */ TokenEOF, TokenEndOfLine, TokenEndOfFunction +}; + +/* used in dynamic memory allocation */ +struct AllocNode +{ + unsigned int Size; + struct AllocNode *NextFree; +}; + +/* whether we're running or skipping code */ +enum RunMode +{ + RunModeRun, /* we're running code as we parse it */ + RunModeSkip, /* skipping code, not running */ + RunModeReturn, /* returning from a function */ + RunModeCaseSearch, /* searching for a case label */ + RunModeBreak, /* breaking out of a switch/while/do */ + RunModeContinue /* as above but repeat the loop */ +}; + +/* parser state - has all this detail so we can parse nested files */ +struct ParseState +{ + const unsigned char *Pos; + const char *FileName; + short int Line; + short int CharacterPos; + enum RunMode Mode; /* whether to skip or run code */ + int SearchLabel; /* what case label we're searching for */ + short int HashIfLevel; + short int HashIfEvaluateToLevel; + const char *SourceText; +}; + +/* values */ +enum BaseType +{ + TypeVoid, /* no type */ + TypeInt, /* integer */ + TypeShort, /* short integer */ + TypeChar, /* a single character (unsigned) */ + TypeLong, /* long integer */ + TypeUnsignedInt, /* unsigned integer */ + TypeUnsignedShort, /* unsigned short integer */ + TypeUnsignedLong, /* unsigned long integer */ +#ifndef NO_FP + TypeFP, /* floating point */ +#endif + TypeFunction, /* a function */ + TypeMacro, /* a macro */ + TypePointer, /* a pointer */ + TypeArray, /* an array of a sub-type */ + TypeStruct, /* aggregate type */ + TypeUnion, /* merged type */ + TypeEnum, /* enumerated integer type */ + Type_Type /* a type for storing types */ +}; + +/* data type */ +struct ValueType +{ + enum BaseType Base; /* what kind of type this is */ + int ArraySize; /* the size of an array type */ + int Sizeof; /* the storage required */ + int AlignBytes; /* the alignment boundary of this type */ + const char *Identifier; /* the name of a struct or union */ + struct ValueType *FromType; /* the type we're derived from (or NULL) */ + struct ValueType *DerivedTypeList; /* first in a list of types derived from this one */ + struct ValueType *Next; /* next item in the derived type list */ + struct Table *Members; /* members of a struct or union */ + int OnHeap; /* true if allocated on the heap */ + int StaticQualifier; /* true if it's a static */ +}; + +/* function definition */ +struct FuncDef +{ + struct ValueType *ReturnType; /* the return value type */ + int NumParams; /* the number of parameters */ + int VarArgs; /* has a variable number of arguments after the explicitly specified ones */ + struct ValueType **ParamType; /* array of parameter types */ + char **ParamName; /* array of parameter names */ + void (*Intrinsic)(); /* intrinsic call address or NULL */ + struct ParseState Body; /* lexical tokens of the function body if not intrinsic */ +}; + +/* macro definition */ +struct MacroDef +{ + int NumParams; /* the number of parameters */ + char **ParamName; /* array of parameter names */ + struct ParseState Body; /* lexical tokens of the function body if not intrinsic */ +}; + +/* values */ +union AnyValue +{ + unsigned char Character; + short ShortInteger; + int Integer; + long LongInteger; + unsigned short UnsignedShortInteger; + unsigned int UnsignedInteger; + unsigned long UnsignedLongInteger; + char *Identifier; + char ArrayMem[2]; /* placeholder for where the data starts, doesn't point to it */ + struct ValueType *Typ; + struct FuncDef FuncDef; + struct MacroDef MacroDef; +#ifndef NO_FP + double FP; +#endif + void *Pointer; /* unsafe native pointers */ +}; + +struct Value +{ + struct ValueType *Typ; /* the type of this value */ + union AnyValue *Val; /* pointer to the AnyValue which holds the actual content */ + struct Value *LValueFrom; /* if an LValue, this is a Value our LValue is contained within (or NULL) */ + char ValOnHeap; /* the AnyValue is on the heap (but this Value is on the stack) */ + char ValOnStack; /* the AnyValue is on the stack along with this Value */ + char IsLValue; /* is modifiable and is allocated somewhere we can usefully modify it */ +}; + +/* hash table data structure */ +struct TableEntry +{ + struct TableEntry *Next; /* next item in this hash chain */ + const char *DeclFileName; /* where the variable was declared */ + unsigned short DeclLine; + unsigned short DeclColumn; + + union TableEntryPayload + { + struct ValueEntry + { + char *Key; /* points to the shared string table */ + struct Value *Val; /* the value we're storing */ + } v; /* used for tables of values */ + + char Key[1]; /* dummy size - used for the shared string table */ + } p; +}; + +struct Table +{ + short Size; + short OnHeap; + struct TableEntry **HashTable; +}; + +/* stack frame for function calls */ +struct StackFrame +{ + struct ParseState ReturnParser; /* how we got here */ + const char *FuncName; /* the name of the function we're in */ + struct Value *ReturnValue; /* copy the return value here */ + struct Value **Parameter; /* array of parameter values */ + int NumParams; /* the number of parameters */ + struct Table LocalTable; /* the local variables and parameters */ + struct TableEntry *LocalHashTable[LOCAL_TABLE_SIZE]; + struct StackFrame *PreviousStackFrame; /* the next lower stack frame */ +}; + +/* lexer state */ +enum LexMode +{ + LexModeNormal, + LexModeHashInclude, + LexModeHashDefine, + LexModeHashDefineSpace, + LexModeHashDefineSpaceIdent +}; + +struct LexState +{ + const char *Pos; + const char *End; + const char *FileName; + int Line; + int CharacterPos; + const char *SourceText; + enum LexMode Mode; + int EmitExtraNewlines; +}; + +/* library function definition */ +struct LibraryFunction +{ + void (*Func)(struct ParseState *Parser, struct Value *, struct Value **, int); + const char *Prototype; +}; + +/* output stream-type specific state information */ +union OutputStreamInfo +{ + struct StringOutputStream + { + struct ParseState *Parser; + char *WritePos; + } Str; +}; + +/* stream-specific method for writing characters to the console */ +typedef void CharWriter(unsigned char, union OutputStreamInfo *); + +/* used when writing output to a string - eg. sprintf() */ +struct OutputStream +{ + CharWriter *Putch; + union OutputStreamInfo i; +}; + +/* possible results of parsing a statement */ +enum ParseResult { ParseResultEOF, ParseResultError, ParseResultOk }; + +/* globals */ +extern void *HeapStackTop; +extern struct Table GlobalTable; +extern struct StackFrame *TopStackFrame; +extern struct ValueType UberType; +extern struct ValueType IntType; +extern struct ValueType CharType; +#ifndef NO_FP +extern struct ValueType FPType; +#endif +extern struct ValueType VoidType; +extern struct ValueType TypeType; +extern struct ValueType FunctionType; +extern struct ValueType MacroType; +extern struct ValueType *CharPtrType; +extern struct ValueType *CharPtrPtrType; +extern struct ValueType *CharArrayType; +extern struct ValueType *VoidPtrType; +extern char *StrEmpty; +extern struct PointerValue NULLPointer; +extern struct LibraryFunction CLibrary[]; +extern struct LibraryFunction PlatformLibrary[]; +extern IOFILE *CStdOut; + +/* table.c */ +void TableInit(); +char *TableStrRegister(const char *Str); +char *TableStrRegister2(const char *Str, int Len); +void TableInitTable(struct Table *Tbl, struct TableEntry **HashTable, int Size, int OnHeap); +int TableSet(struct Table *Tbl, char *Key, struct Value *Val, const char *DeclFileName, int DeclLine, int DeclColumn); +int TableGet(struct Table *Tbl, const char *Key, struct Value **Val, const char **DeclFileName, int *DeclLine, int *DeclColumn); +struct Value *TableDelete(struct Table *Tbl, const char *Key); +char *TableSetIdentifier(struct Table *Tbl, const char *Ident, int IdentLen); +void TableStrFree(); + +/* lex.c */ +void LexInit(); +void LexCleanup(); +void *LexAnalyse(const char *FileName, const char *Source, int SourceLen, int *TokenLen); +void LexInitParser(struct ParseState *Parser, const char *SourceText, void *TokenSource, const char *FileName, int RunIt); +enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int IncPos); +enum LexToken LexRawPeekToken(struct ParseState *Parser); +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 */ +/* the following are defined in picoc.h: + * void PicocParse(const char *FileName, const char *Source, int SourceLen, int RunIt, int CleanupNow, int CleanupSource); + * void PicocParseInteractive(); */ +enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon); +struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier); +void ParseCleanup(); +void ParserCopyPos(struct ParseState *To, struct ParseState *From); +void ParserCopy(struct ParseState *To, struct ParseState *From); + +/* expression.c */ +int ExpressionParse(struct ParseState *Parser, struct Value **Result); +long ExpressionParseInt(struct ParseState *Parser); +void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct Value *SourceValue, int Force, const char *FuncName, int ParamNo, int AllowPointerCoercion); +long ExpressionCoerceInteger(struct Value *Val); +unsigned long ExpressionCoerceUnsignedInteger(struct Value *Val); +#ifndef NO_FP +double ExpressionCoerceFP(struct Value *Val); +#endif + +/* type.c */ +void TypeInit(); +void TypeCleanup(); +int TypeSize(struct ValueType *Typ, int ArraySize, int Compact); +int TypeSizeValue(struct Value *Val, int Compact); +int TypeStackSizeValue(struct Value *Val); +int TypeLastAccessibleOffset(struct Value *Val); +int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, int *IsStatic); +void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, struct ValueType **Typ, char **Identifier); +void TypeParse(struct ParseState *Parser, struct ValueType **Typ, char **Identifier, int *IsStatic); +struct ValueType *TypeGetMatching(struct ParseState *Parser, struct ValueType *ParentType, enum BaseType Base, int ArraySize, const char *Identifier); +struct ValueType *TypeCreateOpaqueStruct(struct ParseState *Parser, const char *StructName, int Size); + +/* heap.c */ +void HeapInit(int StackSize); +void HeapCleanup(); +void *HeapAllocStack(int Size); +int HeapPopStack(void *Addr, int Size); +void HeapUnpopStack(int Size); +void HeapPushStackFrame(); +int HeapPopStackFrame(); +void *HeapAllocMem(int Size); +void HeapFreeMem(void *Mem); + +/* variable.c */ +void VariableInit(); +void VariableCleanup(); +void VariableFree(struct Value *Val); +void VariableTableCleanup(struct Table *HashTable); +void *VariableAlloc(struct ParseState *Parser, int Size, int OnHeap); +void VariableStackPop(struct ParseState *Parser, struct Value *Var); +struct Value *VariableAllocValueAndData(struct ParseState *Parser, int DataSize, int IsLValue, struct Value *LValueFrom, int OnHeap); +struct Value *VariableAllocValueAndCopy(struct ParseState *Parser, struct Value *FromValue, int OnHeap); +struct Value *VariableAllocValueFromType(struct ParseState *Parser, struct ValueType *Typ, int IsLValue, struct Value *LValueFrom, int OnHeap); +struct Value *VariableAllocValueFromExistingData(struct ParseState *Parser, struct ValueType *Typ, union AnyValue *FromValue, int IsLValue, struct Value *LValueFrom); +struct Value *VariableAllocValueShared(struct ParseState *Parser, struct Value *FromValue); +struct Value *VariableDefine(struct ParseState *Parser, char *Ident, struct Value *InitValue, struct ValueType *Typ, int MakeWritable); +struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser, char *Ident, struct ValueType *Typ, int IsStatic, int *FirstVisit); +int VariableDefined(const char *Ident); +void VariableGet(struct ParseState *Parser, const char *Ident, struct Value **LVal); +void VariableDefinePlatformVar(struct ParseState *Parser, char *Ident, struct ValueType *Typ, union AnyValue *FromValue, int IsWritable); +void VariableStackFrameAdd(struct ParseState *Parser, const char *FuncName, int NumParams); +void VariableStackFramePop(struct ParseState *Parser); +struct Value *VariableStringLiteralGet(char *Ident); +void VariableStringLiteralDefine(char *Ident, struct Value *Val); +void *VariableDereferencePointer(struct ParseState *Parser, struct Value *PointerValue, struct Value **DerefVal, int *DerefOffset, struct ValueType **DerefType, int *DerefIsLValue); + +/* clibrary.c */ +void BasicIOInit(); +void LibraryInit(); +void LibraryAdd(struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction *FuncList); +void CLibraryInit(); +void PrintCh(char OutCh, IOFILE *Stream); +void PrintSimpleInt(long Num, IOFILE *Stream); +void PrintInt(long Num, int FieldWidth, int ZeroPad, int LeftJustify, IOFILE *Stream); +void PrintStr(const char *Str, IOFILE *Stream); +void PrintFP(double Num, IOFILE *Stream); +void PrintType(struct ValueType *Typ, IOFILE *Stream); +void LibPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs); + +/* platform.c */ +/* the following are defined in picoc.h: + * void PicocCallMain(int argc, char **argv); + * int PicocPlatformSetExitPoint(); + * void PicocInitialise(int StackSize); + * void PicocCleanup(); + * void PicocPlatformScanFile(const char *FileName); + * extern int PicocExitValue; */ +void ProgramFail(struct ParseState *Parser, const char *Message, ...); +void AssignFail(struct ParseState *Parser, const char *Format, struct ValueType *Type1, struct ValueType *Type2, int Num1, int Num2, const char *FuncName, int ParamNo); +void LexFail(struct LexState *Lexer, const char *Message, ...); +void PlatformCleanup(); +char *PlatformGetLine(char *Buf, int MaxLen, const char *Prompt); +int PlatformGetCharacter(); +void PlatformPutc(unsigned char OutCh, union OutputStreamInfo *); +void PlatformErrorPrefix(struct ParseState *Parser); +void PlatformPrintf(const char *Format, ...); +void PlatformVPrintf(const char *Format, va_list Args); +void PlatformExit(int ExitVal); +void PlatformLibraryInit(); + +/* include.c */ +void IncludeInit(); +void IncludeCleanup(); +void IncludeRegister(const char *IncludeName, void (*SetupFunction)(void), struct LibraryFunction *FuncList, const char *SetupCSource); +void IncludeFile(char *Filename); +/* the following is defined in picoc.h: + * void PicocIncludeAllSystemHeaders(); */ + +/* stdio.c */ +extern const char StdioDefs[]; +extern struct LibraryFunction StdioFunctions[]; +void StdioSetupFunc(void); + +/* math.c */ +extern struct LibraryFunction MathFunctions[]; +void MathSetupFunc(void); + +/* string.c */ +extern struct LibraryFunction StringFunctions[]; +void StringSetupFunc(void); + +/* stdlib.c */ +extern struct LibraryFunction StdlibFunctions[]; +void StdlibSetupFunc(void); + +/* time.c */ +extern const char StdTimeDefs[]; +extern struct LibraryFunction StdTimeFunctions[]; +void StdTimeSetupFunc(void); + +/* errno.c */ +void StdErrnoSetupFunc(void); + +/* ctype.c */ +extern struct LibraryFunction StdCtypeFunctions[]; + +/* stdbool.c */ +extern const char StdboolDefs[]; +void StdboolSetupFunc(void); + +/* unistd.c */ +extern const char UnistdDefs[]; +extern struct LibraryFunction UnistdFunctions[]; +void UnistdSetupFunc(void); + +#endif /* INTERPRETER_H */ diff --git a/lex.c b/lex.c index eb423ad..c0d2f8f 100644 --- a/lex.c +++ b/lex.c @@ -1,4 +1,4 @@ -#include "picoc.h" +#include "interpreter.h" #ifdef NO_CTYPE #define isalpha(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z')) diff --git a/parse.c b/parse.c index 72f93c9..c21a61d 100644 --- a/parse.c +++ b/parse.c @@ -1,4 +1,5 @@ #include "picoc.h" +#include "interpreter.h" /* a chunk of heap-allocated tokens we'll cleanup when we're done */ struct CleanupTokenNode @@ -773,7 +774,7 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi } /* quick scan a source file for definitions */ -void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt, int CleanupNow, int CleanupSource) +void PicocParse(const char *FileName, const char *Source, int SourceLen, int RunIt, int CleanupNow, int CleanupSource) { struct ParseState Parser; enum ParseResult Ok; @@ -814,14 +815,14 @@ void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt, i } /* parse interactively */ -void ParseInteractive() +void PicocParseInteractive() { struct ParseState Parser; enum ParseResult Ok; PlatformPrintf(INTERACTIVE_PROMPT_START); LexInitParser(&Parser, NULL, NULL, StrEmpty, TRUE); - PlatformSetExitPoint(); + PicocPlatformSetExitPoint(); LexInteractiveClear(&Parser); do diff --git a/picoc.c b/picoc.c index b95e55b..130b1d1 100644 --- a/picoc.c +++ b/picoc.c @@ -1,89 +1,19 @@ #include "picoc.h" -#define CALL_MAIN_NO_ARGS_RETURN_VOID "main();" -#define CALL_MAIN_WITH_ARGS_RETURN_VOID "main(__argc,__argv);" -#define CALL_MAIN_NO_ARGS_RETURN_INT "__exit_value = main();" -#define CALL_MAIN_WITH_ARGS_RETURN_INT "__exit_value = main(__argc,__argv);" - -/* initialise everything */ -void Initialise(int StackSize) -{ - BasicIOInit(); - HeapInit(StackSize); - TableInit(); - VariableInit(); - LexInit(); - TypeInit(); -#ifndef NO_HASH_INCLUDE - IncludeInit(); -#endif - LibraryInit(); -#ifdef BUILTIN_MINI_STDLIB - LibraryAdd(&GlobalTable, "c library", &CLibrary[0]); - CLibraryInit(); -#endif - PlatformLibraryInit(); -} - -/* free memory */ -void Cleanup() -{ - PlatformCleanup(); -#ifndef NO_HASH_INCLUDE - IncludeCleanup(); -#endif - ParseCleanup(); - LexCleanup(); - VariableCleanup(); - TypeCleanup(); - TableStrFree(); - HeapCleanup(); -} - /* platform-dependent code for running programs is in this file */ + #ifdef UNIX_HOST -void CallMain(int argc, char **argv) -{ - /* check if the program wants arguments */ - struct Value *FuncValue = NULL; +#include +#include +#include - if (!VariableDefined(TableStrRegister("main"))) - ProgramFail(NULL, "main() is not defined"); - - VariableGet(NULL, TableStrRegister("main"), &FuncValue); - if (FuncValue->Typ->Base != TypeFunction) - ProgramFail(NULL, "main is not a function - can't call it"); - - if (FuncValue->Val->FuncDef.NumParams != 0) - { - /* define the arguments */ - VariableDefinePlatformVar(NULL, "__argc", &IntType, (union AnyValue *)&argc, FALSE); - VariableDefinePlatformVar(NULL, "__argv", CharPtrPtrType, (union AnyValue *)&argv, FALSE); - } - - if (FuncValue->Val->FuncDef.ReturnType == &VoidType) - { - if (FuncValue->Val->FuncDef.NumParams == 0) - Parse("startup", CALL_MAIN_NO_ARGS_RETURN_VOID, strlen(CALL_MAIN_NO_ARGS_RETURN_VOID), TRUE, TRUE, FALSE); - else - Parse("startup", CALL_MAIN_WITH_ARGS_RETURN_VOID, strlen(CALL_MAIN_WITH_ARGS_RETURN_VOID), TRUE, TRUE, FALSE); - } - else - { - VariableDefinePlatformVar(NULL, "__exit_value", &IntType, (union AnyValue *)&ExitValue, TRUE); - - if (FuncValue->Val->FuncDef.NumParams == 0) - Parse("startup", CALL_MAIN_NO_ARGS_RETURN_INT, strlen(CALL_MAIN_NO_ARGS_RETURN_INT), TRUE, TRUE, FALSE); - else - Parse("startup", CALL_MAIN_WITH_ARGS_RETURN_INT, strlen(CALL_MAIN_WITH_ARGS_RETURN_INT), TRUE, TRUE, FALSE); - } -} +#define PICOC_STACK_SIZE (128*1024) /* space for the the stack */ int main(int argc, char **argv) { int ParamCount = 1; int DontRunMain = FALSE; - int StackSize = getenv("STACKSIZE") ? atoi(getenv("STACKSIZE")) : STACK_SIZE; + int StackSize = getenv("STACKSIZE") ? atoi(getenv("STACKSIZE")) : PICOC_STACK_SIZE; if (argc < 2) { @@ -93,46 +23,48 @@ int main(int argc, char **argv) exit(1); } - Initialise(StackSize); + PicocInitialise(StackSize); if (strcmp(argv[ParamCount], "-s") == 0 || strcmp(argv[ParamCount], "-m") == 0) { DontRunMain = TRUE; - IncludeAllSystemHeaders(); + PicocIncludeAllSystemHeaders(); ParamCount++; } if (argc > ParamCount && strcmp(argv[ParamCount], "-i") == 0) { - IncludeAllSystemHeaders(); - ParseInteractive(); + PicocIncludeAllSystemHeaders(); + PicocParseInteractive(); } else { - if (PlatformSetExitPoint()) + if (PicocPlatformSetExitPoint()) { - Cleanup(); - return ExitValue; + PicocCleanup(); + return PicocExitValue; } for (; ParamCount < argc && strcmp(argv[ParamCount], "-") != 0; ParamCount++) - PlatformScanFile(argv[ParamCount]); + PicocPlatformScanFile(argv[ParamCount]); if (!DontRunMain) - CallMain(argc - ParamCount, &argv[ParamCount]); + PicocCallMain(argc - ParamCount, &argv[ParamCount]); } - Cleanup(); - return ExitValue; + PicocCleanup(); + return PicocExitValue; } #else # ifdef SURVEYOR_HOST +# define HEAP_SIZE C_HEAPSIZE + int picoc(char *SourceStr) { char *pos; - Initialise(HEAP_SIZE); + PicocInitialise(HEAP_SIZE); if (SourceStr) { @@ -146,18 +78,19 @@ int picoc(char *SourceStr) } ExitBuf[40] = 0; - PlatformSetExitPoint(); + PicocPlatformSetExitPoint(); if (ExitBuf[40]) { printf("leaving picoC\n\r"); - Cleanup(); + PicocCleanup(); return ExitValue; } if (SourceStr) - Parse("nofile", SourceStr, strlen(SourceStr), TRUE, TRUE, FALSE); + PicocParse("nofile", SourceStr, strlen(SourceStr), TRUE, TRUE, FALSE); - ParseInteractive(); - Cleanup(); + PicocParseInteractive(); + PicocCleanup(); + return ExitValue; } # endif diff --git a/picoc.h b/picoc.h index 3809260..2417233 100644 --- a/picoc.h +++ b/picoc.h @@ -1,8 +1,6 @@ #ifndef PICOC_H #define PICOC_H -#include "platform.h" - /* picoc version number */ #ifdef VER #define PICOC_VERSION "v2.1 beta r" VER /* VER is the subversion version number, obtained via the Makefile */ @@ -16,480 +14,21 @@ #define FALSE 0 #endif -#ifndef NULL -#define NULL 0 -#endif - -#ifndef min -#define min(x,y) (((x)<(y))?(x):(y)) -#endif - -#define MEM_ALIGN(x) (((x) + sizeof(ALIGN_TYPE) - 1) & ~(sizeof(ALIGN_TYPE)-1)) - -#define GETS_BUF_MAX 256 - -/* small processors use a simplified FILE * for stdio, otherwise use the system FILE * */ -#ifdef BUILTIN_MINI_STDLIB -typedef struct OutputStream IOFILE; -#else -typedef FILE IOFILE; -#endif - -/* coercion of numeric types to other numeric types */ -#ifndef NO_FP -#define IS_FP(v) ((v)->Typ->Base == TypeFP) -#define FP_VAL(v) ((v)->Val->FP) -#else -#define IS_FP(v) 0 -#define FP_VAL(v) 0 -#endif - -#define IS_POINTER_COERCIBLE(v, ap) ((ap) ? ((v)->Typ->Base == TypePointer) : 0) -#define POINTER_COERCE(v) ((int)(v)->Val->Pointer) - -#define IS_INTEGER_NUMERIC_TYPE(t) ((t)->Base >= TypeInt && (t)->Base <= TypeUnsignedLong) -#define IS_INTEGER_NUMERIC(v) IS_INTEGER_NUMERIC_TYPE((v)->Typ) -#define IS_NUMERIC_COERCIBLE(v) (IS_INTEGER_NUMERIC(v) || IS_FP(v)) -#define IS_NUMERIC_COERCIBLE_PLUS_POINTERS(v,ap) (IS_NUMERIC_COERCIBLE(v) || IS_POINTER_COERCIBLE(v,ap)) - - -struct Table; - -/* lexical tokens */ -enum LexToken -{ - /* 0x00 */ TokenNone, - /* 0x01 */ TokenComma, - /* 0x02 */ TokenAssign, TokenAddAssign, TokenSubtractAssign, TokenMultiplyAssign, TokenDivideAssign, TokenModulusAssign, - /* 0x08 */ TokenShiftLeftAssign, TokenShiftRightAssign, TokenArithmeticAndAssign, TokenArithmeticOrAssign, TokenArithmeticExorAssign, - /* 0x0d */ TokenQuestionMark, TokenColon, - /* 0x0f */ TokenLogicalOr, - /* 0x10 */ TokenLogicalAnd, - /* 0x11 */ TokenArithmeticOr, - /* 0x12 */ TokenArithmeticExor, - /* 0x13 */ TokenAmpersand, - /* 0x14 */ TokenEqual, TokenNotEqual, - /* 0x16 */ TokenLessThan, TokenGreaterThan, TokenLessEqual, TokenGreaterEqual, - /* 0x1a */ TokenShiftLeft, TokenShiftRight, - /* 0x1c */ TokenPlus, TokenMinus, - /* 0x1e */ TokenAsterisk, TokenSlash, TokenModulus, - /* 0x21 */ TokenIncrement, TokenDecrement, TokenUnaryNot, TokenUnaryExor, TokenSizeof, TokenCast, - /* 0x27 */ TokenLeftSquareBracket, TokenRightSquareBracket, TokenDot, TokenArrow, - /* 0x2b */ TokenOpenBracket, TokenCloseBracket, - /* 0x2d */ TokenIdentifier, TokenIntegerConstant, TokenFPConstant, TokenStringConstant, TokenCharacterConstant, - /* 0x32 */ TokenSemicolon, TokenEllipsis, - /* 0x34 */ TokenLeftBrace, TokenRightBrace, - /* 0x36 */ TokenIntType, TokenCharType, TokenFloatType, TokenDoubleType, TokenVoidType, TokenEnumType, - /* 0x3c */ TokenLongType, TokenSignedType, TokenShortType, TokenStaticType, TokenAutoType, TokenRegisterType, TokenExternType, TokenStructType, TokenUnionType, TokenUnsignedType, TokenTypedef, - /* 0x46 */ TokenContinue, TokenDo, TokenElse, TokenFor, TokenIf, TokenWhile, TokenBreak, TokenSwitch, TokenCase, TokenDefault, TokenReturn, - /* 0x51 */ TokenHashDefine, TokenHashInclude, TokenHashIf, TokenHashIfdef, TokenHashIfndef, TokenHashElse, TokenHashEndif, - /* 0x58 */ TokenNew, TokenDelete, - /* 0x5a */ TokenOpenMacroBracket, - /* 0x5b */ TokenEOF, TokenEndOfLine, TokenEndOfFunction -}; - -/* used in dynamic memory allocation */ -struct AllocNode -{ - unsigned int Size; - struct AllocNode *NextFree; -}; - -/* whether we're running or skipping code */ -enum RunMode -{ - RunModeRun, /* we're running code as we parse it */ - RunModeSkip, /* skipping code, not running */ - RunModeReturn, /* returning from a function */ - RunModeCaseSearch, /* searching for a case label */ - RunModeBreak, /* breaking out of a switch/while/do */ - RunModeContinue /* as above but repeat the loop */ -}; - -/* parser state - has all this detail so we can parse nested files */ -struct ParseState -{ - const unsigned char *Pos; - const char *FileName; - short int Line; - short int CharacterPos; - enum RunMode Mode; /* whether to skip or run code */ - int SearchLabel; /* what case label we're searching for */ - short int HashIfLevel; - short int HashIfEvaluateToLevel; - const char *SourceText; -}; - -/* values */ -enum BaseType -{ - TypeVoid, /* no type */ - TypeInt, /* integer */ - TypeShort, /* short integer */ - TypeChar, /* a single character (unsigned) */ - TypeLong, /* long integer */ - TypeUnsignedInt, /* unsigned integer */ - TypeUnsignedShort, /* unsigned short integer */ - TypeUnsignedLong, /* unsigned long integer */ -#ifndef NO_FP - TypeFP, /* floating point */ -#endif - TypeFunction, /* a function */ - TypeMacro, /* a macro */ - TypePointer, /* a pointer */ - TypeArray, /* an array of a sub-type */ - TypeStruct, /* aggregate type */ - TypeUnion, /* merged type */ - TypeEnum, /* enumerated integer type */ - Type_Type /* a type for storing types */ -}; - -/* data type */ -struct ValueType -{ - enum BaseType Base; /* what kind of type this is */ - int ArraySize; /* the size of an array type */ - int Sizeof; /* the storage required */ - int AlignBytes; /* the alignment boundary of this type */ - const char *Identifier; /* the name of a struct or union */ - struct ValueType *FromType; /* the type we're derived from (or NULL) */ - struct ValueType *DerivedTypeList; /* first in a list of types derived from this one */ - struct ValueType *Next; /* next item in the derived type list */ - struct Table *Members; /* members of a struct or union */ - int OnHeap; /* true if allocated on the heap */ - int StaticQualifier; /* true if it's a static */ -}; - -/* function definition */ -struct FuncDef -{ - struct ValueType *ReturnType; /* the return value type */ - int NumParams; /* the number of parameters */ - int VarArgs; /* has a variable number of arguments after the explicitly specified ones */ - struct ValueType **ParamType; /* array of parameter types */ - char **ParamName; /* array of parameter names */ - void (*Intrinsic)(); /* intrinsic call address or NULL */ - struct ParseState Body; /* lexical tokens of the function body if not intrinsic */ -}; - -/* macro definition */ -struct MacroDef -{ - int NumParams; /* the number of parameters */ - char **ParamName; /* array of parameter names */ - struct ParseState Body; /* lexical tokens of the function body if not intrinsic */ -}; - -/* values */ -union AnyValue -{ - unsigned char Character; - short ShortInteger; - int Integer; - long LongInteger; - unsigned short UnsignedShortInteger; - unsigned int UnsignedInteger; - unsigned long UnsignedLongInteger; - char *Identifier; - char ArrayMem[2]; /* placeholder for where the data starts, doesn't point to it */ - struct ValueType *Typ; - struct FuncDef FuncDef; - struct MacroDef MacroDef; -#ifndef NO_FP - double FP; -#endif - void *Pointer; /* unsafe native pointers */ -}; - -struct Value -{ - struct ValueType *Typ; /* the type of this value */ - union AnyValue *Val; /* pointer to the AnyValue which holds the actual content */ - struct Value *LValueFrom; /* if an LValue, this is a Value our LValue is contained within (or NULL) */ - char ValOnHeap; /* the AnyValue is on the heap (but this Value is on the stack) */ - char ValOnStack; /* the AnyValue is on the stack along with this Value */ - char IsLValue; /* is modifiable and is allocated somewhere we can usefully modify it */ -}; - -/* hash table data structure */ -struct TableEntry -{ - struct TableEntry *Next; /* next item in this hash chain */ - const char *DeclFileName; /* where the variable was declared */ - unsigned short DeclLine; - unsigned short DeclColumn; - - union TableEntryPayload - { - struct ValueEntry - { - char *Key; /* points to the shared string table */ - struct Value *Val; /* the value we're storing */ - } v; /* used for tables of values */ - - char Key[1]; /* dummy size - used for the shared string table */ - } p; -}; - -struct Table -{ - short Size; - short OnHeap; - struct TableEntry **HashTable; -}; - -/* stack frame for function calls */ -struct StackFrame -{ - struct ParseState ReturnParser; /* how we got here */ - const char *FuncName; /* the name of the function we're in */ - struct Value *ReturnValue; /* copy the return value here */ - struct Value **Parameter; /* array of parameter values */ - int NumParams; /* the number of parameters */ - struct Table LocalTable; /* the local variables and parameters */ - struct TableEntry *LocalHashTable[LOCAL_TABLE_SIZE]; - struct StackFrame *PreviousStackFrame; /* the next lower stack frame */ -}; - -/* lexer state */ -enum LexMode -{ - LexModeNormal, - LexModeHashInclude, - LexModeHashDefine, - LexModeHashDefineSpace, - LexModeHashDefineSpaceIdent -}; - -struct LexState -{ - const char *Pos; - const char *End; - const char *FileName; - int Line; - int CharacterPos; - const char *SourceText; - enum LexMode Mode; - int EmitExtraNewlines; -}; - -/* library function definition */ -struct LibraryFunction -{ - void (*Func)(struct ParseState *Parser, struct Value *, struct Value **, int); - const char *Prototype; -}; - -/* output stream-type specific state information */ -union OutputStreamInfo -{ - struct StringOutputStream - { - struct ParseState *Parser; - char *WritePos; - } Str; -}; - -/* stream-specific method for writing characters to the console */ -typedef void CharWriter(unsigned char, union OutputStreamInfo *); - -/* used when writing output to a string - eg. sprintf() */ -struct OutputStream -{ - CharWriter *Putch; - union OutputStreamInfo i; -}; - -/* possible results of parsing a statement */ -enum ParseResult { ParseResultEOF, ParseResultError, ParseResultOk }; - -/* globals */ -extern void *HeapStackTop; -extern struct Table GlobalTable; -extern struct StackFrame *TopStackFrame; -extern struct ValueType UberType; -extern struct ValueType IntType; -extern struct ValueType CharType; -#ifndef NO_FP -extern struct ValueType FPType; -#endif -extern struct ValueType VoidType; -extern struct ValueType TypeType; -extern struct ValueType FunctionType; -extern struct ValueType MacroType; -extern struct ValueType *CharPtrType; -extern struct ValueType *CharPtrPtrType; -extern struct ValueType *CharArrayType; -extern struct ValueType *VoidPtrType; -extern char *StrEmpty; -extern struct PointerValue NULLPointer; -extern struct LibraryFunction CLibrary[]; -extern struct LibraryFunction PlatformLibrary[]; -extern IOFILE *CStdOut; - -/* table.c */ -void TableInit(); -char *TableStrRegister(const char *Str); -char *TableStrRegister2(const char *Str, int Len); -void TableInitTable(struct Table *Tbl, struct TableEntry **HashTable, int Size, int OnHeap); -int TableSet(struct Table *Tbl, char *Key, struct Value *Val, const char *DeclFileName, int DeclLine, int DeclColumn); -int TableGet(struct Table *Tbl, const char *Key, struct Value **Val, const char **DeclFileName, int *DeclLine, int *DeclColumn); -struct Value *TableDelete(struct Table *Tbl, const char *Key); -char *TableSetIdentifier(struct Table *Tbl, const char *Ident, int IdentLen); -void TableStrFree(); - -/* lex.c */ -void LexInit(); -void LexCleanup(); -void *LexAnalyse(const char *FileName, const char *Source, int SourceLen, int *TokenLen); -void LexInitParser(struct ParseState *Parser, const char *SourceText, void *TokenSource, const char *FileName, int RunIt); -enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int IncPos); -enum LexToken LexRawPeekToken(struct ParseState *Parser); -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 */ -enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon); -struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier); -void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt, int CleanupNow, int CleanupSource); -void ParseInteractive(); -void ParseCleanup(); -void ParserCopyPos(struct ParseState *To, struct ParseState *From); -void ParserCopy(struct ParseState *To, struct ParseState *From); - -/* expression.c */ -int ExpressionParse(struct ParseState *Parser, struct Value **Result); -long ExpressionParseInt(struct ParseState *Parser); -void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct Value *SourceValue, int Force, const char *FuncName, int ParamNo, int AllowPointerCoercion); -long ExpressionCoerceInteger(struct Value *Val); -unsigned long ExpressionCoerceUnsignedInteger(struct Value *Val); -#ifndef NO_FP -double ExpressionCoerceFP(struct Value *Val); -#endif - -/* type.c */ -void TypeInit(); -void TypeCleanup(); -int TypeSize(struct ValueType *Typ, int ArraySize, int Compact); -int TypeSizeValue(struct Value *Val, int Compact); -int TypeStackSizeValue(struct Value *Val); -int TypeLastAccessibleOffset(struct Value *Val); -int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, int *IsStatic); -void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, struct ValueType **Typ, char **Identifier); -void TypeParse(struct ParseState *Parser, struct ValueType **Typ, char **Identifier, int *IsStatic); -struct ValueType *TypeGetMatching(struct ParseState *Parser, struct ValueType *ParentType, enum BaseType Base, int ArraySize, const char *Identifier); -struct ValueType *TypeCreateOpaqueStruct(struct ParseState *Parser, const char *StructName, int Size); - -/* heap.c */ -void HeapInit(int StackSize); -void HeapCleanup(); -void *HeapAllocStack(int Size); -int HeapPopStack(void *Addr, int Size); -void HeapUnpopStack(int Size); -void HeapPushStackFrame(); -int HeapPopStackFrame(); -void *HeapAllocMem(int Size); -void HeapFreeMem(void *Mem); - -/* variable.c */ -void VariableInit(); -void VariableCleanup(); -void VariableFree(struct Value *Val); -void VariableTableCleanup(struct Table *HashTable); -void *VariableAlloc(struct ParseState *Parser, int Size, int OnHeap); -void VariableStackPop(struct ParseState *Parser, struct Value *Var); -struct Value *VariableAllocValueAndData(struct ParseState *Parser, int DataSize, int IsLValue, struct Value *LValueFrom, int OnHeap); -struct Value *VariableAllocValueAndCopy(struct ParseState *Parser, struct Value *FromValue, int OnHeap); -struct Value *VariableAllocValueFromType(struct ParseState *Parser, struct ValueType *Typ, int IsLValue, struct Value *LValueFrom, int OnHeap); -struct Value *VariableAllocValueFromExistingData(struct ParseState *Parser, struct ValueType *Typ, union AnyValue *FromValue, int IsLValue, struct Value *LValueFrom); -struct Value *VariableAllocValueShared(struct ParseState *Parser, struct Value *FromValue); -struct Value *VariableDefine(struct ParseState *Parser, char *Ident, struct Value *InitValue, struct ValueType *Typ, int MakeWritable); -struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser, char *Ident, struct ValueType *Typ, int IsStatic, int *FirstVisit); -int VariableDefined(const char *Ident); -void VariableGet(struct ParseState *Parser, const char *Ident, struct Value **LVal); -void VariableDefinePlatformVar(struct ParseState *Parser, char *Ident, struct ValueType *Typ, union AnyValue *FromValue, int IsWritable); -void VariableStackFrameAdd(struct ParseState *Parser, const char *FuncName, int NumParams); -void VariableStackFramePop(struct ParseState *Parser); -struct Value *VariableStringLiteralGet(char *Ident); -void VariableStringLiteralDefine(char *Ident, struct Value *Val); -void *VariableDereferencePointer(struct ParseState *Parser, struct Value *PointerValue, struct Value **DerefVal, int *DerefOffset, struct ValueType **DerefType, int *DerefIsLValue); - -/* clibrary.c */ -void BasicIOInit(); -void LibraryInit(); -void LibraryAdd(struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction *FuncList); -void CLibraryInit(); -void PrintCh(char OutCh, IOFILE *Stream); -void PrintSimpleInt(long Num, IOFILE *Stream); -void PrintInt(long Num, int FieldWidth, int ZeroPad, int LeftJustify, IOFILE *Stream); -void PrintStr(const char *Str, IOFILE *Stream); -void PrintFP(double Num, IOFILE *Stream); -void PrintType(struct ValueType *Typ, IOFILE *Stream); -void LibPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs); +void PicocParse(const char *FileName, const char *Source, int SourceLen, int RunIt, int CleanupNow, int CleanupSource); +void PicocParseInteractive(); /* platform.c */ -void ProgramFail(struct ParseState *Parser, const char *Message, ...); -void AssignFail(struct ParseState *Parser, const char *Format, struct ValueType *Type1, struct ValueType *Type2, int Num1, int Num2, const char *FuncName, int ParamNo); -void LexFail(struct LexState *Lexer, const char *Message, ...); -void PlatformCleanup(); -void PlatformScanFile(const char *FileName); -char *PlatformGetLine(char *Buf, int MaxLen, const char *Prompt); -int PlatformGetCharacter(); -void PlatformPutc(unsigned char OutCh, union OutputStreamInfo *); -void PlatformErrorPrefix(struct ParseState *Parser); -void PlatformPrintf(const char *Format, ...); -void PlatformVPrintf(const char *Format, va_list Args); -void PlatformExit(int ExitVal); -void PlatformLibraryInit(); -void Initialise(); -void Cleanup(); -extern int ExitValue; +void PicocCallMain(int argc, char **argv); +int PicocPlatformSetExitPoint(); +void PicocInitialise(int StackSize); +void PicocCleanup(); +void PicocPlatformScanFile(const char *FileName); + +extern int PicocExitValue; /* include.c */ -void IncludeInit(); -void IncludeCleanup(); -void IncludeRegister(const char *IncludeName, void (*SetupFunction)(void), struct LibraryFunction *FuncList, const char *SetupCSource); -void IncludeFile(char *Filename); -void IncludeAllSystemHeaders(); - -/* stdio.c */ -extern const char StdioDefs[]; -extern struct LibraryFunction StdioFunctions[]; -void StdioSetupFunc(void); - -/* math.c */ -extern struct LibraryFunction MathFunctions[]; -void MathSetupFunc(void); - -/* string.c */ -extern struct LibraryFunction StringFunctions[]; -void StringSetupFunc(void); - -/* stdlib.c */ -extern struct LibraryFunction StdlibFunctions[]; -void StdlibSetupFunc(void); - -/* time.c */ -extern const char StdTimeDefs[]; -extern struct LibraryFunction StdTimeFunctions[]; -void StdTimeSetupFunc(void); - -/* errno.c */ -void StdErrnoSetupFunc(void); - -/* ctype.c */ -extern struct LibraryFunction StdCtypeFunctions[]; - -/* stdbool.c */ -extern const char StdboolDefs[]; -void StdboolSetupFunc(void); - -/* unistd.c */ -extern const char UnistdDefs[]; -extern struct LibraryFunction UnistdFunctions[]; -void UnistdSetupFunc(void); +void PicocIncludeAllSystemHeaders(); #endif /* PICOC_H */ diff --git a/platform.c b/platform.c index 1359f08..2bb23e0 100644 --- a/platform.c +++ b/platform.c @@ -1,7 +1,89 @@ #include "picoc.h" +#include "interpreter.h" /* the value passed to exit() */ -int ExitValue = 0; +int PicocExitValue = 0; + +/* initialise everything */ +void PicocInitialise(int StackSize) +{ + BasicIOInit(); + HeapInit(StackSize); + TableInit(); + VariableInit(); + LexInit(); + TypeInit(); +#ifndef NO_HASH_INCLUDE + IncludeInit(); +#endif + LibraryInit(); +#ifdef BUILTIN_MINI_STDLIB + LibraryAdd(&GlobalTable, "c library", &CLibrary[0]); + CLibraryInit(); +#endif + PlatformLibraryInit(); +} + +/* free memory */ +void PicocCleanup() +{ + PlatformCleanup(); +#ifndef NO_HASH_INCLUDE + IncludeCleanup(); +#endif + ParseCleanup(); + LexCleanup(); + VariableCleanup(); + TypeCleanup(); + TableStrFree(); + HeapCleanup(); +} + +/* platform-dependent code for running programs */ +#ifdef UNIX_HOST + +#define CALL_MAIN_NO_ARGS_RETURN_VOID "main();" +#define CALL_MAIN_WITH_ARGS_RETURN_VOID "main(__argc,__argv);" +#define CALL_MAIN_NO_ARGS_RETURN_INT "__exit_value = main();" +#define CALL_MAIN_WITH_ARGS_RETURN_INT "__exit_value = main(__argc,__argv);" + +void PicocCallMain(int argc, char **argv) +{ + /* check if the program wants arguments */ + struct Value *FuncValue = NULL; + + if (!VariableDefined(TableStrRegister("main"))) + ProgramFail(NULL, "main() is not defined"); + + VariableGet(NULL, TableStrRegister("main"), &FuncValue); + if (FuncValue->Typ->Base != TypeFunction) + ProgramFail(NULL, "main is not a function - can't call it"); + + if (FuncValue->Val->FuncDef.NumParams != 0) + { + /* define the arguments */ + VariableDefinePlatformVar(NULL, "__argc", &IntType, (union AnyValue *)&argc, FALSE); + VariableDefinePlatformVar(NULL, "__argv", CharPtrPtrType, (union AnyValue *)&argv, FALSE); + } + + if (FuncValue->Val->FuncDef.ReturnType == &VoidType) + { + if (FuncValue->Val->FuncDef.NumParams == 0) + PicocParse("startup", CALL_MAIN_NO_ARGS_RETURN_VOID, strlen(CALL_MAIN_NO_ARGS_RETURN_VOID), TRUE, TRUE, FALSE); + else + PicocParse("startup", CALL_MAIN_WITH_ARGS_RETURN_VOID, strlen(CALL_MAIN_WITH_ARGS_RETURN_VOID), TRUE, TRUE, FALSE); + } + else + { + VariableDefinePlatformVar(NULL, "__exit_value", &IntType, (union AnyValue *)&PicocExitValue, TRUE); + + if (FuncValue->Val->FuncDef.NumParams == 0) + PicocParse("startup", CALL_MAIN_NO_ARGS_RETURN_INT, strlen(CALL_MAIN_NO_ARGS_RETURN_INT), TRUE, TRUE, FALSE); + else + PicocParse("startup", CALL_MAIN_WITH_ARGS_RETURN_INT, strlen(CALL_MAIN_WITH_ARGS_RETURN_INT), TRUE, TRUE, FALSE); + } +} +#endif void PrintSourceTextErrorLine(const char *FileName, const char *SourceText, int Line, int CharacterPos) { diff --git a/platform.h b/platform.h index 791a8e2..a4dfa42 100644 --- a/platform.h +++ b/platform.h @@ -30,14 +30,8 @@ #define INTERACTIVE_PROMPT_STATEMENT "picoc> " #define INTERACTIVE_PROMPT_LINE " > " -#define PlatformSetExitPoint() setjmp(ExitBuf) - -/* defines for the optional "fdlibm" maths library */ -#define _IEEE_LIBM - /* host platform includes */ #ifdef UNIX_HOST -# define STACK_SIZE (128*1024) /* space for the the stack */ # define USE_MALLOC_STACK /* stack is allocated using malloc() */ # define USE_MALLOC_HEAP /* heap is allocated using malloc() */ # include @@ -124,8 +118,6 @@ extern jmp_buf ExitBuf; # define calloc(a,b) mon_malloc(a*b) # define realloc mon_realloc # define free mon_free -# undef PlatformSetExitPoint -# define PlatformSetExitPoint() # endif # endif diff --git a/platform/library_ffox.c b/platform/library_ffox.c index 93bf999..9e68e62 100644 --- a/platform/library_ffox.c +++ b/platform/library_ffox.c @@ -1,4 +1,4 @@ -#include "../picoc.h" +#include "../interpreter.h" /* list of all library functions and their prototypes */ struct LibraryFunction PlatformLibrary[] = diff --git a/platform/library_srv1.c b/platform/library_srv1.c index 78e2c08..ff76f1b 100644 --- a/platform/library_srv1.c +++ b/platform/library_srv1.c @@ -1,4 +1,4 @@ -#include "../picoc.h" +#include "../interpreter.h" static int Blobcnt, Blobx1, Blobx2, Bloby1, Bloby2, Iy1, Iy2, Iu1, Iu2, Iv1, Iv2; static int GPSlat, GPSlon, GPSalt, GPSfix, GPSsat, GPSutc, Elcount, Ercount; @@ -325,9 +325,9 @@ void Cvpix(struct ParseState *Parser, struct Value *ReturnValue, struct Value ** x = Param[0]->Val->Integer; y = Param[1]->Val->Integer; ix = vpix((unsigned char *)FRAME_BUF, x, y); - Iy1 = ((ix>>16) & 0x000000FF); // Y1 - Iu1 = ((ix>>24) & 0x000000FF); // U - Iv1 = ((ix>>8) & 0x000000FF); // V + Iy1 = ((ix>>16) & 0x000000FF); // Y1 + Iu1 = ((ix>>24) & 0x000000FF); // U + Iv1 = ((ix>>8) & 0x000000FF); // V } void Cvscan(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) @@ -345,11 +345,11 @@ void Cvscan(struct ParseState *Parser, struct Value *ReturnValue, struct Value * void Cvmean(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { - vmean((unsigned char *)FRAME_BUF); + vmean((unsigned char *)FRAME_BUF); Iy1 = mean[0]; Iu1 = mean[1]; Iv1 = mean[2]; -} +} // search for blob by color, index; return center point X,Y and width Z void Cvblob(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { @@ -706,7 +706,7 @@ void Cnnlearnblob (struct ParseState *Parser, struct Value *ReturnValue, struct bloby1[0], bloby2[0], imgWidth, imgHeight); nnpack8x8(ix); nndisplay(ix); -} +} void Cautorun (struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { int ix, t0; diff --git a/platform/library_surveyor.c b/platform/library_surveyor.c index 0dd3470..c3dc415 100644 --- a/platform/library_surveyor.c +++ b/platform/library_surveyor.c @@ -1,4 +1,4 @@ -#include "../picoc.h" +#include "../interpreter.h" static int Blobcnt, Blobx1, Blobx2, Bloby1, Bloby2, Iy1, Iy2, Iu1, Iu2, Iv1, Iv2; static int Cxmin, Cxmax, Cymin, Cymax; diff --git a/platform/library_unix.c b/platform/library_unix.c index 36866c4..0308702 100644 --- a/platform/library_unix.c +++ b/platform/library_unix.c @@ -1,4 +1,4 @@ -#include "../picoc.h" +#include "../interpreter.h" void UnixSetupFunc() { diff --git a/platform/platform_ffox.c b/platform/platform_ffox.c index b00c217..ea7bd7e 100644 --- a/platform/platform_ffox.c +++ b/platform/platform_ffox.c @@ -1,4 +1,4 @@ -#include "../picoc.h" +#include "../interpreter.h" /* deallocate any storage */ void PlatformCleanup() diff --git a/platform/platform_surveyor.c b/platform/platform_surveyor.c index 9f0f95b..7d8c314 100644 --- a/platform/platform_surveyor.c +++ b/platform/platform_surveyor.c @@ -1,4 +1,4 @@ -#include "../picoc.h" +#include "../interpreter.h" /* deallocate any storage */ diff --git a/platform/platform_unix.c b/platform/platform_unix.c index fc86be3..f53ac01 100644 --- a/platform/platform_unix.c +++ b/platform/platform_unix.c @@ -1,4 +1,5 @@ #include "../picoc.h" +#include "../interpreter.h" #ifdef USE_READLINE #include @@ -82,20 +83,26 @@ char *PlatformReadFile(const char *FileName) } /* read and scan a file for definitions */ -void PlatformScanFile(const char *FileName) +void PicocPlatformScanFile(const char *FileName) { char *SourceStr = PlatformReadFile(FileName); - Parse(FileName, SourceStr, strlen(SourceStr), TRUE, FALSE, TRUE); + PicocParse(FileName, SourceStr, strlen(SourceStr), TRUE, FALSE, TRUE); } /* mark where to end the program for platforms which require this */ jmp_buf ExitBuf; +/* set the point we'll return to when we exit through an error */ +int PicocPlatformSetExitPoint() +{ + return setjmp(ExitBuf); +} + /* exit the program */ void PlatformExit(int RetVal) { - ExitValue = RetVal; + PicocExitValue = RetVal; longjmp(ExitBuf, 1); } diff --git a/table.c b/table.c index a02a41f..0554ffa 100644 --- a/table.c +++ b/table.c @@ -1,4 +1,4 @@ -#include "picoc.h" +#include "interpreter.h" struct Table StringTable; struct TableEntry *StringHashTable[STRING_TABLE_SIZE]; diff --git a/type.c b/type.c index bf4f178..5e7944d 100644 --- a/type.c +++ b/type.c @@ -1,4 +1,4 @@ -#include "picoc.h" +#include "interpreter.h" /* some basic types */ struct ValueType UberType; diff --git a/variable.c b/variable.c index aeab6c6..4ced0d9 100644 --- a/variable.c +++ b/variable.c @@ -1,4 +1,4 @@ -#include "picoc.h" +#include "interpreter.h" /* maximum size of a value to temporarily copy while we create a variable */ #define MAX_TMP_COPY_BUF 256