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