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
This commit is contained in:
zik.saleeba 2011-02-17 07:11:20 +00:00
parent fbe799d63f
commit b23d1e8e06
30 changed files with 659 additions and 609 deletions

View file

@ -1,4 +1,5 @@
#include "picoc.h"
#include "interpreter.h"
/* the picoc version string */
static const char *VersionString = NULL;

View file

@ -1,6 +1,6 @@
/* string.h library for large systems - small embedded systems use clibrary.c instead */
#include <ctype.h>
#include "../picoc.h"
#include "../interpreter.h"
#ifndef BUILTIN_MINI_STDLIB

View file

@ -1,6 +1,6 @@
/* string.h library for large systems - small embedded systems use clibrary.c instead */
#include <errno.h>
#include "../picoc.h"
#include "../interpreter.h"
#ifndef BUILTIN_MINI_STDLIB

View file

@ -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

View file

@ -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

View file

@ -1,6 +1,6 @@
/* stdio.h library for large systems - small embedded systems use clibrary.c instead */
#include <errno.h>
#include "../picoc.h"
#include "../interpreter.h"
#ifndef BUILTIN_MINI_STDLIB

View file

@ -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

View file

@ -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

View file

@ -1,6 +1,6 @@
/* string.h library for large systems - small embedded systems use clibrary.c instead */
#include <time.h>
#include "../picoc.h"
#include "../interpreter.h"
#ifndef BUILTIN_MINI_STDLIB

View file

@ -2,7 +2,7 @@
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include "../picoc.h"
#include "../interpreter.h"
#ifndef BUILTIN_MINI_STDLIB

View file

@ -1,4 +1,4 @@
#include "picoc.h"
#include "interpreter.h"
/* whether evaluation is left to right for a given precedence level */

2
heap.c
View file

@ -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 */

View file

@ -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 */

494
interpreter.h Normal file
View file

@ -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 */

2
lex.c
View file

@ -1,4 +1,4 @@
#include "picoc.h"
#include "interpreter.h"
#ifdef NO_CTYPE
#define isalpha(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))

View file

@ -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

119
picoc.c
View file

@ -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 <stdlib.h>
#include <stdio.h>
#include <string.h>
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

481
picoc.h
View file

@ -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 */

View file

@ -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)
{

View file

@ -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 <stdio.h>
@ -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

View file

@ -1,4 +1,4 @@
#include "../picoc.h"
#include "../interpreter.h"
/* list of all library functions and their prototypes */
struct LibraryFunction PlatformLibrary[] =

View file

@ -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;

View file

@ -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;

View file

@ -1,4 +1,4 @@
#include "../picoc.h"
#include "../interpreter.h"
void UnixSetupFunc()
{

View file

@ -1,4 +1,4 @@
#include "../picoc.h"
#include "../interpreter.h"
/* deallocate any storage */
void PlatformCleanup()

View file

@ -1,4 +1,4 @@
#include "../picoc.h"
#include "../interpreter.h"
/* deallocate any storage */

View file

@ -1,4 +1,5 @@
#include "../picoc.h"
#include "../interpreter.h"
#ifdef USE_READLINE
#include <readline/readline.h>
@ -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);
}

View file

@ -1,4 +1,4 @@
#include "picoc.h"
#include "interpreter.h"
struct Table StringTable;
struct TableEntry *StringHashTable[STRING_TABLE_SIZE];

2
type.c
View file

@ -1,4 +1,4 @@
#include "picoc.h"
#include "interpreter.h"
/* some basic types */
struct ValueType UberType;

View file

@ -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