Xv6 with picoc & Linkage editor  v1.0
The project delineate mutual cohesion between c library, linkage editor ( linker), interpreter and operating system by porting the same on xv6 kernel
interpreter.h
00001 #ifndef INTERPRETER_H
00002 #define INTERPRETER_H
00003 
00004 #include "platform.h"
00005 
00006 /* handy definitions */
00007 #ifndef TRUE
00008 #define TRUE 1
00009 #define FALSE 0
00010 #endif
00011 
00012 #ifndef NULL
00013 #define NULL 0
00014 #endif
00015 
00016 #ifndef min
00017 #define min(x,y) (((x)<(y))?(x):(y))
00018 #endif
00019 
00020 #define MEM_ALIGN(x) (((x) + sizeof(ALIGN_TYPE) - 1) & ~(sizeof(ALIGN_TYPE)-1))
00021 
00022 #define GETS_BUF_MAX 256
00023 
00024 /* small processors use a simplified FILE * for stdio, otherwise use the system FILE * */
00025 #ifdef BUILTIN_MINI_STDLIB
00026 typedef struct OutputStream IOFILE;
00027 #else
00028 typedef FILE IOFILE;
00029 #endif
00030 
00031 /* coercion of numeric types to other numeric types */
00032 #ifndef NO_FP
00033 #define IS_FP(v) ((v)->Typ->Base == TypeFP)
00034 #define FP_VAL(v) ((v)->Val->FP)
00035 #else
00036 #define IS_FP(v) 0
00037 #define FP_VAL(v) 0
00038 #endif
00039 
00040 #define IS_POINTER_COERCIBLE(v, ap) ((ap) ? ((v)->Typ->Base == TypePointer) : 0)
00041 #define POINTER_COERCE(v) ((int)(v)->Val->Pointer)
00042 
00043 #define IS_INTEGER_NUMERIC_TYPE(t) ((t)->Base >= TypeInt && (t)->Base <= TypeUnsignedLong)
00044 #define IS_INTEGER_NUMERIC(v) IS_INTEGER_NUMERIC_TYPE((v)->Typ)
00045 #define IS_NUMERIC_COERCIBLE(v) (IS_INTEGER_NUMERIC(v) || IS_FP(v))
00046 #define IS_NUMERIC_COERCIBLE_PLUS_POINTERS(v,ap) (IS_NUMERIC_COERCIBLE(v) || IS_POINTER_COERCIBLE(v,ap))
00047 
00048 
00049 struct Table;
00050 
00051 /* lexical tokens */
00052 enum LexToken
00053 {
00054     /* 0x00 */ TokenNone, 
00055     /* 0x01 */ TokenComma,
00056     /* 0x02 */ TokenAssign, TokenAddAssign, TokenSubtractAssign, TokenMultiplyAssign, TokenDivideAssign, TokenModulusAssign,
00057     /* 0x08 */ TokenShiftLeftAssign, TokenShiftRightAssign, TokenArithmeticAndAssign, TokenArithmeticOrAssign, TokenArithmeticExorAssign,
00058     /* 0x0d */ TokenQuestionMark, TokenColon, 
00059     /* 0x0f */ TokenLogicalOr, 
00060     /* 0x10 */ TokenLogicalAnd, 
00061     /* 0x11 */ TokenArithmeticOr, 
00062     /* 0x12 */ TokenArithmeticExor, 
00063     /* 0x13 */ TokenAmpersand, 
00064     /* 0x14 */ TokenEqual, TokenNotEqual, 
00065     /* 0x16 */ TokenLessThan, TokenGreaterThan, TokenLessEqual, TokenGreaterEqual,
00066     /* 0x1a */ TokenShiftLeft, TokenShiftRight, 
00067     /* 0x1c */ TokenPlus, TokenMinus, 
00068     /* 0x1e */ TokenAsterisk, TokenSlash, TokenModulus,
00069     /* 0x21 */ TokenIncrement, TokenDecrement, TokenUnaryNot, TokenUnaryExor, TokenSizeof, TokenCast,
00070     /* 0x27 */ TokenLeftSquareBracket, TokenRightSquareBracket, TokenDot, TokenArrow, 
00071     /* 0x2b */ TokenOpenBracket, TokenCloseBracket,
00072     /* 0x2d */ TokenIdentifier, TokenIntegerConstant, TokenFPConstant, TokenStringConstant, TokenCharacterConstant,
00073     /* 0x32 */ TokenSemicolon, TokenEllipsis,
00074     /* 0x34 */ TokenLeftBrace, TokenRightBrace,
00075     /* 0x36 */ TokenIntType, TokenCharType, TokenFloatType, TokenDoubleType, TokenVoidType, TokenEnumType,
00076     /* 0x3c */ TokenLongType, TokenSignedType, TokenShortType, TokenStaticType, TokenAutoType, TokenRegisterType, TokenExternType, TokenStructType, TokenUnionType, TokenUnsignedType, TokenTypedef,
00077     /* 0x46 */ TokenContinue, TokenDo, TokenElse, TokenFor, TokenGoto, TokenIf, TokenWhile, TokenBreak, TokenSwitch, TokenCase, TokenDefault, TokenReturn,
00078     /* 0x52 */ TokenHashDefine, TokenHashInclude, TokenHashIf, TokenHashIfdef, TokenHashIfndef, TokenHashElse, TokenHashEndif,
00079     /* 0x59 */ TokenNew, TokenDelete,
00080     /* 0x5b */ TokenOpenMacroBracket,
00081     /* 0x5c */ TokenEOF, TokenEndOfLine, TokenEndOfFunction
00082 };
00083 
00084 /* used in dynamic memory allocation */
00085 struct AllocNode
00086 {
00087     unsigned int Size;
00088     struct AllocNode *NextFree;
00089 };
00090 
00091 /* whether we're running or skipping code */
00092 enum RunMode
00093 {
00094     RunModeRun,                 /* we're running code as we parse it */
00095     RunModeSkip,                /* skipping code, not running */
00096     RunModeReturn,              /* returning from a function */
00097     RunModeCaseSearch,          /* searching for a case label */
00098     RunModeBreak,               /* breaking out of a switch/while/do */
00099     RunModeContinue,            /* as above but repeat the loop */
00100     RunModeGoto                 /* searching for a goto label */
00101 };
00102 
00103 /* parser state - has all this detail so we can parse nested files */
00104 struct ParseState
00105 {
00106     const unsigned char *Pos;
00107     const char *FileName;
00108     short int Line;
00109     short int CharacterPos;
00110     enum RunMode Mode;          /* whether to skip or run code */
00111     int SearchLabel;            /* what case label we're searching for */
00112     const char *SearchGotoLabel;/* what goto label we're searching for */
00113     short int HashIfLevel;
00114     short int HashIfEvaluateToLevel;
00115     const char *SourceText;
00116 };
00117 
00118 /* values */
00119 enum BaseType
00120 {
00121     TypeVoid,                   /* no type */
00122     TypeInt,                    /* integer */
00123     TypeShort,                  /* short integer */
00124     TypeChar,                   /* a single character (unsigned) */
00125     TypeLong,                   /* long integer */
00126     TypeUnsignedInt,            /* unsigned integer */
00127     TypeUnsignedShort,          /* unsigned short integer */
00128     TypeUnsignedLong,           /* unsigned long integer */
00129 #ifndef NO_FP
00130     TypeFP,                     /* floating point */
00131 #endif
00132     TypeFunction,               /* a function */
00133     TypeMacro,                  /* a macro */
00134     TypePointer,                /* a pointer */
00135     TypeArray,                  /* an array of a sub-type */
00136     TypeStruct,                 /* aggregate type */
00137     TypeUnion,                  /* merged type */
00138     TypeEnum,                   /* enumerated integer type */
00139     TypeGotoLabel,              /* a label we can "goto" */
00140     Type_Type                   /* a type for storing types */
00141 };
00142 
00143 /* data type */
00144 struct ValueType
00145 {
00146     enum BaseType Base;             /* what kind of type this is */
00147     int ArraySize;                  /* the size of an array type */
00148     int Sizeof;                     /* the storage required */
00149     int AlignBytes;                 /* the alignment boundary of this type */
00150     const char *Identifier;         /* the name of a struct or union */
00151     struct ValueType *FromType;     /* the type we're derived from (or NULL) */
00152     struct ValueType *DerivedTypeList;  /* first in a list of types derived from this one */
00153     struct ValueType *Next;         /* next item in the derived type list */
00154     struct Table *Members;          /* members of a struct or union */
00155     int OnHeap;                     /* true if allocated on the heap */
00156     int StaticQualifier;            /* true if it's a static */
00157 };
00158 
00159 /* function definition */
00160 struct FuncDef
00161 {
00162     struct ValueType *ReturnType;   /* the return value type */
00163     int NumParams;                  /* the number of parameters */
00164     int VarArgs;                    /* has a variable number of arguments after the explicitly specified ones */
00165     struct ValueType **ParamType;   /* array of parameter types */
00166     char **ParamName;               /* array of parameter names */
00167     void (*Intrinsic)();            /* intrinsic call address or NULL */
00168     struct ParseState Body;         /* lexical tokens of the function body if not intrinsic */
00169 };
00170 
00171 /* macro definition */
00172 struct MacroDef
00173 {
00174     int NumParams;                  /* the number of parameters */
00175     char **ParamName;               /* array of parameter names */
00176     struct ParseState Body;         /* lexical tokens of the function body if not intrinsic */
00177 };
00178 
00179 /* values */
00180 union AnyValue
00181 {
00182     unsigned char Character;
00183     short ShortInteger;
00184     int Integer;
00185     long LongInteger;
00186     unsigned short UnsignedShortInteger;
00187     unsigned int UnsignedInteger;
00188     unsigned long UnsignedLongInteger;
00189     char *Identifier;
00190     char ArrayMem[2];               /* placeholder for where the data starts, doesn't point to it */
00191     struct ValueType *Typ;
00192     struct FuncDef FuncDef;
00193     struct MacroDef MacroDef;
00194 #ifndef NO_FP
00195     double FP;
00196 #endif
00197     void *Pointer;                  /* unsafe native pointers */
00198 };
00199 
00200 struct Value
00201 {
00202     struct ValueType *Typ;          /* the type of this value */
00203     union AnyValue *Val;            /* pointer to the AnyValue which holds the actual content */
00204     struct Value *LValueFrom;       /* if an LValue, this is a Value our LValue is contained within (or NULL) */
00205     char ValOnHeap;                 /* the AnyValue is on the heap (but this Value is on the stack) */
00206     char ValOnStack;                /* the AnyValue is on the stack along with this Value */
00207     char IsLValue;                  /* is modifiable and is allocated somewhere we can usefully modify it */
00208 };
00209 
00210 /* hash table data structure */
00211 struct TableEntry
00212 {
00213     struct TableEntry *Next;        /* next item in this hash chain */
00214     const char *DeclFileName;       /* where the variable was declared */
00215     unsigned short DeclLine;
00216     unsigned short DeclColumn;
00217 
00218     union TableEntryPayload
00219     {
00220         struct ValueEntry
00221         {
00222             char *Key;              /* points to the shared string table */
00223             struct Value *Val;      /* the value we're storing */
00224         } v;                        /* used for tables of values */
00225         
00226         char Key[1];                /* dummy size - used for the shared string table */
00227     } p;
00228 };
00229     
00230 struct Table
00231 {
00232     short Size;
00233     short OnHeap;
00234     struct TableEntry **HashTable;
00235 };
00236 
00237 /* stack frame for function calls */
00238 struct StackFrame
00239 {
00240     struct ParseState ReturnParser;         /* how we got here */
00241     const char *FuncName;                   /* the name of the function we're in */
00242     struct Value *ReturnValue;              /* copy the return value here */
00243     struct Value **Parameter;               /* array of parameter values */
00244     int NumParams;                          /* the number of parameters */
00245     struct Table LocalTable;                /* the local variables and parameters */
00246     struct TableEntry *LocalHashTable[LOCAL_TABLE_SIZE];
00247     struct StackFrame *PreviousStackFrame;  /* the next lower stack frame */
00248 };
00249 
00250 /* lexer state */
00251 enum LexMode
00252 {
00253     LexModeNormal,
00254     LexModeHashInclude,
00255     LexModeHashDefine,
00256     LexModeHashDefineSpace,
00257     LexModeHashDefineSpaceIdent
00258 };
00259 
00260 struct LexState
00261 {
00262     const char *Pos;
00263     const char *End;
00264     const char *FileName;
00265     int Line;
00266     int CharacterPos;
00267     const char *SourceText;
00268     enum LexMode Mode;
00269     int EmitExtraNewlines;
00270 };
00271 
00272 /* library function definition */
00273 struct LibraryFunction
00274 {
00275     void (*Func)(struct ParseState *Parser, struct Value *, struct Value **, int);
00276     const char *Prototype;
00277 };
00278 
00279 /* output stream-type specific state information */
00280 union OutputStreamInfo
00281 {
00282     struct StringOutputStream
00283     {
00284         struct ParseState *Parser;
00285         char *WritePos;
00286     } Str;
00287 };
00288 
00289 /* stream-specific method for writing characters to the console */
00290 typedef void CharWriter(unsigned char, union OutputStreamInfo *);
00291 
00292 /* used when writing output to a string - eg. sprintf() */
00293 struct OutputStream
00294 {
00295     CharWriter *Putch;
00296     union OutputStreamInfo i;
00297 };
00298 
00299 /* possible results of parsing a statement */
00300 enum ParseResult { ParseResultEOF, ParseResultError, ParseResultOk };
00301 
00302 /* globals */
00303 extern void *HeapStackTop;
00304 extern struct Table GlobalTable;
00305 extern struct StackFrame *TopStackFrame;
00306 extern struct ValueType UberType;
00307 extern struct ValueType IntType;
00308 extern struct ValueType CharType;
00309 #ifndef NO_FP
00310 extern struct ValueType FPType;
00311 #endif
00312 extern struct ValueType VoidType;
00313 extern struct ValueType TypeType;
00314 extern struct ValueType FunctionType;
00315 extern struct ValueType MacroType;
00316 extern struct ValueType GotoLabelType;
00317 extern struct ValueType *CharPtrType;
00318 extern struct ValueType *CharPtrPtrType;
00319 extern struct ValueType *CharArrayType;
00320 extern struct ValueType *VoidPtrType;
00321 extern char *StrEmpty;
00322 extern struct PointerValue NULLPointer;
00323 extern struct LibraryFunction CLibrary[];
00324 extern struct LibraryFunction PlatformLibrary[];
00325 extern IOFILE *CStdOut;
00326 
00327 /* table.c */
00328 void TableInit();
00329 char *TableStrRegister(const char *Str);
00330 char *TableStrRegister2(const char *Str, int Len);
00331 void TableInitTable(struct Table *Tbl, struct TableEntry **HashTable, int Size, int OnHeap);
00332 int TableSet(struct Table *Tbl, char *Key, struct Value *Val, const char *DeclFileName, int DeclLine, int DeclColumn);
00333 int TableGet(struct Table *Tbl, const char *Key, struct Value **Val, const char **DeclFileName, int *DeclLine, int *DeclColumn);
00334 struct Value *TableDelete(struct Table *Tbl, const char *Key);
00335 char *TableSetIdentifier(struct Table *Tbl, const char *Ident, int IdentLen);
00336 void TableStrFree();
00337 
00338 /* lex.c */
00339 void LexInit();
00340 void LexCleanup();
00341 void *LexAnalyse(const char *FileName, const char *Source, int SourceLen, int *TokenLen);
00342 void LexInitParser(struct ParseState *Parser, const char *SourceText, void *TokenSource, const char *FileName, int RunIt);
00343 enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int IncPos);
00344 enum LexToken LexRawPeekToken(struct ParseState *Parser);
00345 void LexToEndOfLine(struct ParseState *Parser);
00346 void *LexCopyTokens(struct ParseState *StartParser, struct ParseState *EndParser);
00347 void LexInteractiveClear(struct ParseState *Parser);
00348 void LexInteractiveCompleted(struct ParseState *Parser);
00349 void LexInteractiveStatementPrompt();
00350 
00351 /* parse.c */
00352 /* the following are defined in picoc.h:
00353  * void PicocParse(const char *FileName, const char *Source, int SourceLen, int RunIt, int CleanupNow, int CleanupSource);
00354  * void PicocParseInteractive(); */
00355 enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon);
00356 struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier);
00357 void ParseCleanup();
00358 void ParserCopyPos(struct ParseState *To, struct ParseState *From);
00359 void ParserCopy(struct ParseState *To, struct ParseState *From);
00360 
00361 /* expression.c */
00362 int ExpressionParse(struct ParseState *Parser, struct Value **Result);
00363 long ExpressionParseInt(struct ParseState *Parser);
00364 void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct Value *SourceValue, int Force, const char *FuncName, int ParamNo, int AllowPointerCoercion);
00365 long ExpressionCoerceInteger(struct Value *Val);
00366 unsigned long ExpressionCoerceUnsignedInteger(struct Value *Val);
00367 #ifndef NO_FP
00368 double ExpressionCoerceFP(struct Value *Val);
00369 #endif
00370 
00371 /* type.c */
00372 void TypeInit();
00373 void TypeCleanup();
00374 int TypeSize(struct ValueType *Typ, int ArraySize, int Compact);
00375 int TypeSizeValue(struct Value *Val, int Compact);
00376 int TypeStackSizeValue(struct Value *Val);
00377 int TypeLastAccessibleOffset(struct Value *Val);
00378 int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ, int *IsStatic);
00379 void TypeParseIdentPart(struct ParseState *Parser, struct ValueType *BasicTyp, struct ValueType **Typ, char **Identifier);
00380 void TypeParse(struct ParseState *Parser, struct ValueType **Typ, char **Identifier, int *IsStatic);
00381 struct ValueType *TypeGetMatching(struct ParseState *Parser, struct ValueType *ParentType, enum BaseType Base, int ArraySize, const char *Identifier, int AllowDuplicates);
00382 struct ValueType *TypeCreateOpaqueStruct(struct ParseState *Parser, const char *StructName, int Size);
00383 
00384 /* heap.c */
00385 void HeapInit(int StackSize);
00386 void HeapCleanup();
00387 void *HeapAllocStack(int Size);
00388 int HeapPopStack(void *Addr, int Size);
00389 void HeapUnpopStack(int Size);
00390 void HeapPushStackFrame();
00391 int HeapPopStackFrame();
00392 void *HeapAllocMem(int Size);
00393 void HeapFreeMem(void *Mem);
00394 
00395 /* variable.c */
00396 void VariableInit();
00397 void VariableCleanup();
00398 void VariableFree(struct Value *Val);
00399 void VariableTableCleanup(struct Table *HashTable);
00400 void *VariableAlloc(struct ParseState *Parser, int Size, int OnHeap);
00401 void VariableStackPop(struct ParseState *Parser, struct Value *Var);
00402 struct Value *VariableAllocValueAndData(struct ParseState *Parser, int DataSize, int IsLValue, struct Value *LValueFrom, int OnHeap);
00403 struct Value *VariableAllocValueAndCopy(struct ParseState *Parser, struct Value *FromValue, int OnHeap);
00404 struct Value *VariableAllocValueFromType(struct ParseState *Parser, struct ValueType *Typ, int IsLValue, struct Value *LValueFrom, int OnHeap);
00405 struct Value *VariableAllocValueFromExistingData(struct ParseState *Parser, struct ValueType *Typ, union AnyValue *FromValue, int IsLValue, struct Value *LValueFrom);
00406 struct Value *VariableAllocValueShared(struct ParseState *Parser, struct Value *FromValue);
00407 struct Value *VariableDefine(struct ParseState *Parser, char *Ident, struct Value *InitValue, struct ValueType *Typ, int MakeWritable);
00408 struct Value *VariableDefineButIgnoreIdentical(struct ParseState *Parser, char *Ident, struct ValueType *Typ, int IsStatic, int *FirstVisit);
00409 int VariableDefined(const char *Ident);
00410 void VariableGet(struct ParseState *Parser, const char *Ident, struct Value **LVal);
00411 void VariableDefinePlatformVar(struct ParseState *Parser, char *Ident, struct ValueType *Typ, union AnyValue *FromValue, int IsWritable);
00412 void VariableStackFrameAdd(struct ParseState *Parser, const char *FuncName, int NumParams);
00413 void VariableStackFramePop(struct ParseState *Parser);
00414 struct Value *VariableStringLiteralGet(char *Ident);
00415 void VariableStringLiteralDefine(char *Ident, struct Value *Val);
00416 void *VariableDereferencePointer(struct ParseState *Parser, struct Value *PointerValue, struct Value **DerefVal, int *DerefOffset, struct ValueType **DerefType, int *DerefIsLValue);
00417 
00418 /* clibrary.c */
00419 void BasicIOInit();
00420 void LibraryInit();
00421 void LibraryAdd(struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction *FuncList);
00422 void CLibraryInit();
00423 void PrintCh(char OutCh, IOFILE *Stream);
00424 void PrintSimpleInt(long Num, IOFILE *Stream);
00425 void PrintInt(long Num, int FieldWidth, int ZeroPad, int LeftJustify, IOFILE *Stream);
00426 void PrintStr(const char *Str, IOFILE *Stream);
00427 void PrintFP(double Num, IOFILE *Stream);
00428 void PrintType(struct ValueType *Typ, IOFILE *Stream);
00429 void LibPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs);
00430 
00431 /* platform.c */
00432 /* the following are defined in picoc.h:
00433  * void PicocCallMain(int argc, char **argv);
00434  * int PicocPlatformSetExitPoint();
00435  * void PicocInitialise(int StackSize);
00436  * void PicocCleanup();
00437  * void PicocPlatformScanFile(const char *FileName);
00438  * extern int PicocExitValue; */
00439 void ProgramFail(struct ParseState *Parser, const char *Message, ...);
00440 void AssignFail(struct ParseState *Parser, const char *Format, struct ValueType *Type1, struct ValueType *Type2, int Num1, int Num2, const char *FuncName, int ParamNo);
00441 void LexFail(struct LexState *Lexer, const char *Message, ...);
00442 void PlatformCleanup();
00443 char *PlatformGetLine(char *Buf, int MaxLen, const char *Prompt);
00444 int PlatformGetCharacter();
00445 void PlatformPutc(unsigned char OutCh, union OutputStreamInfo *);
00446 void PlatformErrorPrefix(struct ParseState *Parser);
00447 void PlatformPrintf(const char *Format, ...);
00448 void PlatformVPrintf(const char *Format, va_list Args);
00449 void PlatformExit(int ExitVal);
00450 char *PlatformMakeTempName(char *TempNameBuffer);
00451 void PlatformLibraryInit();
00452 
00453 /* include.c */
00454 void IncludeInit();
00455 void IncludeCleanup();
00456 void IncludeRegister(const char *IncludeName, void (*SetupFunction)(void), struct LibraryFunction *FuncList, const char *SetupCSource);
00457 void IncludeFile(char *Filename);
00458 /* the following is defined in picoc.h:
00459  * void PicocIncludeAllSystemHeaders(); */
00460 
00461 /* stdio.c */
00462 extern const char StdioDefs[];
00463 extern struct LibraryFunction StdioFunctions[];
00464 void StdioSetupFunc(void);
00465 
00466 /* math.c */
00467 extern struct LibraryFunction MathFunctions[];
00468 void MathSetupFunc(void);
00469 
00470 /* string.c */
00471 extern struct LibraryFunction StringFunctions[];
00472 void StringSetupFunc(void);
00473 
00474 /* stdlib.c */
00475 extern struct LibraryFunction StdlibFunctions[];
00476 void StdlibSetupFunc(void);
00477 
00478 /* time.c */
00479 extern const char StdTimeDefs[];
00480 extern struct LibraryFunction StdTimeFunctions[];
00481 void StdTimeSetupFunc(void);
00482 
00483 /* errno.c */
00484 void StdErrnoSetupFunc(void);
00485 
00486 /* ctype.c */
00487 extern struct LibraryFunction StdCtypeFunctions[];
00488 
00489 /* stdbool.c */
00490 extern const char StdboolDefs[];
00491 void StdboolSetupFunc(void);
00492 
00493 /* unistd.c */
00494 extern const char UnistdDefs[];
00495 extern struct LibraryFunction UnistdFunctions[];
00496 void UnistdSetupFunc(void);
00497 
00498 #endif /* INTERPRETER_H */
 All Data Structures