/* this is called when the header file is included */ void PlatformLibrarySetup_gpsposition(Picoc *pc) { #ifndef NO_FP const char *definition = "typedef struct {" "long Latitude;" "long Longitude;" "float Altitude;" "float GeoidSeparation;" "float Heading;" "float GroundSpeed;" "float PDOP;" "float HDOP;" "float VDOP;" "unsigned char Status;" "char Satellites;" "} GPSPositionData;"; #else const char *definition = "typedef struct {" "long Latitude;" "long Longitude;" "unsigned char Status;" "char Satellites;" "}GPSPositionData;"; #endif PicocParse(pc, "mylib", definition, strlen(definition), TRUE, TRUE, FALSE, FALSE); if (GPSPositionHandle() == NULL) ProgramFailNoParser(pc, "no gpsposition"); }
/* this is called when the header file is included */ void PlatformLibrarySetup_positionactual(Picoc *pc) { const char *definition = "typedef struct {" "float North;" "float East;" "float Down;" "} PositionActualData;"; PicocParse(pc, "mylib", definition, strlen(definition), TRUE, TRUE, FALSE, FALSE); if (PositionActualHandle() == NULL) ProgramFailNoParser(pc, "no positionactual"); }
/* this is called when the header file is included */ void PlatformLibrarySetup_magnetometer(Picoc *pc) { const char *definition = "typedef struct {" "float x;" "float y;" "float z;" "} MagnetometerData;"; PicocParse(pc, "mylib", definition, strlen(definition), TRUE, TRUE, FALSE, FALSE); if (MagnetometerHandle() == NULL) ProgramFailNoParser(pc, "no magnetometer"); }
/* this is called when the header file is included */ void PlatformLibrarySetup_pathstatus(Picoc *pc) { const char *definition = "typedef struct {" "float fractional_progress;" "float error;" "unsigned char Status;" "} PathStatusData;"; PicocParse(pc, "mylib", definition, strlen(definition), TRUE, TRUE, FALSE, FALSE); if (PathStatusHandle() == NULL) ProgramFailNoParser(pc, "no pathstatus"); }
/* this is called when the header file is included */ void PlatformLibrarySetup_gyros(Picoc *pc) { const char *definition = "typedef struct {" "float x;" "float y;" "float z;" "float temperature;" "} GyrosData;"; PicocParse(pc, "mylib", definition, strlen(definition), TRUE, TRUE, FALSE, FALSE); if (GyrosHandle() == NULL) ProgramFailNoParser(pc, "no gyros"); }
/* this is called when the header file is included */ void PlatformLibrarySetup_baroaltitude(Picoc *pc) { #ifndef NO_FP const char *definition = "typedef struct {" "float Altitude;" "float Temperature;" "float Pressure;" "} BaroAltitudeData;"; PicocParse(pc, "mylib", definition, strlen(definition), TRUE, TRUE, FALSE, FALSE); #endif if (BaroAltitudeHandle() == NULL) ProgramFailNoParser(pc, "no baroaltitude"); }
/* this is called when the header file is included */ void PlatformLibrarySetup_attitudeactual(Picoc *pc) { #ifndef NO_FP const char *definition = "typedef struct {" "float Roll;" "float Pitch;" "float Yaw;" "} AttitudeActualData;"; PicocParse(pc, "mylib", definition, strlen(definition), TRUE, TRUE, FALSE, FALSE); #endif if (AttitudeActualHandle() == NULL) ProgramFailNoParser(pc, "no attitudeactual"); }
/* this is called when the header file is included */ void PlatformLibrarySetup_accels(Picoc *pc) { #ifndef NO_FP const char *definition = "typedef struct {" "float x;" "float y;" "float z;" "float temperature;" "} AccelsData;"; PicocParse(pc, "mylib", definition, strlen(definition), TRUE, TRUE, FALSE, FALSE); #endif if (AccelsHandle() == NULL) ProgramFailNoParser(pc, "no accels"); }
/* this is called when the header file is included */ void PlatformLibrarySetup_pathdesired(Picoc *pc) { const char *definition = "typedef struct {" "float Start[3];" "float End[3];" "float StartingVelocity;" "float EndingVelocity;" "float ModeParameters;" "unsigned char Mode;" "} PathDesiredData;"; PicocParse(pc, "mylib", definition, strlen(definition), TRUE, TRUE, FALSE, FALSE); if (PathDesiredHandle() == NULL) ProgramFailNoParser(pc, "no pathdesired"); }
void PicocCallMain(Picoc *pc, int argc, char **argv) { /* check if the program wants arguments */ struct Value *FuncValue = NULL; if (!VariableDefined(pc, TableStrRegister(pc, "main"))) ProgramFailNoParser(pc, "main() is not defined"); VariableGet(pc, NULL, TableStrRegister(pc, "main"), &FuncValue); if (FuncValue->Typ->Base != TypeFunction) ProgramFailNoParser(pc, "main is not a function - can't call it"); if (FuncValue->Val->FuncDef.NumParams != 0) { /* define the arguments */ VariableDefinePlatformVar(pc, NULL, "__argc", &pc->IntType, (union AnyValue *)&argc, FALSE); VariableDefinePlatformVar(pc, NULL, "__argv", pc->CharPtrPtrType, (union AnyValue *)&argv, FALSE); } if (FuncValue->Val->FuncDef.ReturnType == &pc->VoidType) { if (FuncValue->Val->FuncDef.NumParams == 0) PicocParse(pc, "startup", CALL_MAIN_NO_ARGS_RETURN_VOID, strlen(CALL_MAIN_NO_ARGS_RETURN_VOID), TRUE, TRUE, FALSE, TRUE); else PicocParse(pc, "startup", CALL_MAIN_WITH_ARGS_RETURN_VOID, strlen(CALL_MAIN_WITH_ARGS_RETURN_VOID), TRUE, TRUE, FALSE, TRUE); } else { VariableDefinePlatformVar(pc, NULL, "__exit_value", &pc->IntType, (union AnyValue *)&pc->PicocExitValue, TRUE); if (FuncValue->Val->FuncDef.NumParams == 0) PicocParse(pc, "startup", CALL_MAIN_NO_ARGS_RETURN_INT, strlen(CALL_MAIN_NO_ARGS_RETURN_INT), TRUE, TRUE, FALSE, TRUE); else PicocParse(pc, "startup", CALL_MAIN_WITH_ARGS_RETURN_INT, strlen(CALL_MAIN_WITH_ARGS_RETURN_INT), TRUE, TRUE, FALSE, TRUE); } }
/* read a file into memory */ char *PlatformReadFile(Picoc *pc, const char *FileName) { struct stat FileInfo; char *ReadText; FILE *InFile; int BytesRead; char *p; if (stat(FileName, &FileInfo)) ProgramFailNoParser(pc, "can't read file %s\n", FileName); ReadText = malloc(FileInfo.st_size + 1); if (ReadText == NULL) ProgramFailNoParser(pc, "out of memory\n"); InFile = fopen(FileName, "r"); if (InFile == NULL) ProgramFailNoParser(pc, "can't read file %s\n", FileName); BytesRead = fread(ReadText, 1, FileInfo.st_size, InFile); if (BytesRead == 0) ProgramFailNoParser(pc, "can't read file %s\n", FileName); ReadText[BytesRead] = '\0'; fclose(InFile); if ((ReadText[0] == '#') && (ReadText[1] == '!')) { for (p = ReadText; (*p != '\r') && (*p != '\n'); ++p) { *p = ' '; } } return ReadText; }
/* set an identifier and return the identifier. share if possible */ char *TableSetIdentifier(Picoc *pc, struct Table *Tbl, const char *Ident, int IdentLen){ int AddAt; struct TableEntry *FoundEntry = TableSearchIdentifier(Tbl, Ident, IdentLen, &AddAt); if (FoundEntry != NULL) return &FoundEntry->p.Key[0]; else{ /* add it to the table - we economise by not allocating the whole structure here */ struct TableEntry *NewEntry = HeapAllocMem(pc, sizeof(struct TableEntry) - sizeof(union TableEntryPayload) + IdentLen + 1); if (NewEntry == NULL) ProgramFailNoParser(pc, "out of memory"); strncpy((char *)&NewEntry->p.Key[0], (char *)Ident, IdentLen); NewEntry->p.Key[IdentLen] = '\0'; NewEntry->Next = Tbl->HashTable[AddAt]; Tbl->HashTable[AddAt] = NewEntry; return &NewEntry->p.Key[0]; } }
/* this is called when the header file is included */ void PlatformLibrarySetup_flightbatterystate(Picoc *pc) { #ifndef NO_FP const char *definition = "typedef struct {" "float Voltage;" "float Current;" "float BoardSupplyVoltage;" "float PeakCurrent;" "float AvgCurrent;" "float ConsumedEnergy;" "float EstimatedFlightTime;" "} FlightBatteryStateData;"; PicocParse(pc, "mylib", definition, strlen(definition), TRUE, TRUE, FALSE, FALSE); #endif if (FlightBatteryStateHandle() == NULL) ProgramFailNoParser(pc, "no flightbatterystate"); }
/* set a breakpoint in the table */ void DebugSetBreakpoint(struct ParseState *Parser) { int AddAt; struct TableEntry *FoundEntry = DebugTableSearchBreakpoint(Parser, &AddAt); Picoc *pc = Parser->pc; if (FoundEntry == NULL) { /* add it to the table */ struct TableEntry *NewEntry = HeapAllocMem(pc, sizeof(*NewEntry)); if (NewEntry == NULL) ProgramFailNoParser(pc, "(DebugSetBreakpoint) out of memory"); NewEntry->p.b.FileName = Parser->FileName; NewEntry->p.b.Line = Parser->Line; NewEntry->p.b.CharacterPos = Parser->CharacterPos; NewEntry->Next = pc->BreakpointHashTable[AddAt]; pc->BreakpointHashTable[AddAt] = NewEntry; pc->BreakpointCount++; } }
/* read and scan a file for definitions */ void PicocPlatformScanFileByLine(Picoc *pc, const char *FileName) { FILE *InFile = fopen(FileName, "r"); if (!InFile) ProgramFailNoParser(pc, "can't read file %s\n", FileName); #if 0 /* support this? */ /* ignore "#!/path/to/picoc" .. by replacing the "#!" with "//" */ if (SourceStr != NULL && SourceStr[0] == '#' && SourceStr[1] == '!') { SourceStr[0] = '/'; SourceStr[1] = '/'; } #endif PicocParseLineByLine(pc, FileName, InFile, TRUE); fclose(InFile); }
void LibraryAddConstants(Picoc* pc, LibraryConstant* CstList) { for (int Count = 0; CstList[Count].CstValue != NULL; Count++) { switch (CstList[Count].Type) { case TypeInt: VariableDefinePlatformVar(pc, NULL, CstList[Count].Name, &pc->IntType, CstList[Count].CstValue, FALSE); break; case TypeFP: VariableDefinePlatformVar(pc, NULL, CstList[Count].Name, &pc->FPType, CstList[Count].CstValue, FALSE); break; default: ProgramFailNoParser(pc, "invalid type in LibrairyAdd"); break; } } }
/* quick scan a source file for definitions */ void PicocParse(Picoc *pc, const char *FileName, const char *Source, int SourceLen, int RunIt, int CleanupNow, int CleanupSource, int EnableDebugger) { struct ParseState Parser; enum ParseResult Ok; struct CleanupTokenNode *NewCleanupNode; char *RegFileName = TableStrRegister(pc, FileName); void *Tokens = LexAnalyse(pc, RegFileName, Source, SourceLen, NULL); /* allocate a cleanup node so we can clean up the tokens later */ if (!CleanupNow) { NewCleanupNode = (struct CleanupTokenNode *) HeapCallocMem(pc, sizeof(struct CleanupTokenNode)); if (NewCleanupNode == NULL) ProgramFailNoParser(pc, "out of memory"); NewCleanupNode->Tokens = Tokens; if (CleanupSource) NewCleanupNode->SourceText = Source; else NewCleanupNode->SourceText = NULL; NewCleanupNode->Next = pc->CleanupTokenList; pc->CleanupTokenList = NewCleanupNode; } /* do the parsing */ LexInitParser(&Parser, pc, Source, Tokens, RegFileName, RunIt, EnableDebugger); do { Ok = ParseStatement(&Parser, TRUE); } while (Ok == ParseResultOk); if (Ok == ParseResultError) ProgramFail(&Parser, "parse error"); /* clean up */ if (CleanupNow) HeapFreeMem(pc, Tokens); }
/* produce tokens from the lexer and return a heap buffer with the result - used for scanning */ void *LexTokenise(Picoc *pc, struct LexState *Lexer, int *TokenLen) { enum LexToken Token; void *HeapMem; struct Value *GotValue; int MemUsed = 0; int ValueSize; int ReserveSpace = (Lexer->End - Lexer->Pos) * 4 + 16; void *TokenSpace = HeapAllocStack(pc, ReserveSpace); char *TokenPos = (char *)TokenSpace; int LastCharacterPos = 0; if (TokenSpace == NULL) LexFail(pc, Lexer, "out of memory"); do { /* store the token at the end of the stack area */ Token = LexScanGetToken(pc, Lexer, &GotValue); #ifdef DEBUG_LEXER printf("Token: %02x\n", Token); #endif *(unsigned char *)TokenPos = Token; TokenPos++; MemUsed++; *(unsigned char *)TokenPos = (unsigned char)LastCharacterPos; TokenPos++; MemUsed++; ValueSize = LexTokenSize(Token); if (ValueSize > 0) { /* store a value as well */ memcpy((void *)TokenPos, (void *)GotValue->Val, ValueSize); TokenPos += ValueSize; MemUsed += ValueSize; } LastCharacterPos = Lexer->CharacterPos; } while (Token != TokenEOF); HeapMem = HeapAllocMem(pc, MemUsed); if (HeapMem == NULL) LexFail(pc, Lexer, "out of memory"); if (ReserveSpace < MemUsed) ProgramFailNoParser(pc, "not enough memory"); memcpy(HeapMem, TokenSpace, MemUsed); HeapPopStack(pc, TokenSpace, ReserveSpace); #ifdef DEBUG_LEXER { int Count; printf("Tokens: "); for (Count = 0; Count < MemUsed; Count++) printf("%02x ", *((unsigned char *)HeapMem+Count)); printf("\n"); } #endif if (TokenLen) *TokenLen = MemUsed; return HeapMem; }
/* this is called when the header file is included */ void PlatformLibrarySetup_attitudeactual(Picoc *pc) { if (AttitudeActualHandle() == NULL) ProgramFailNoParser(pc, "no attitudeactual"); }
/* this is called when the header file is included */ void PlatformLibrarySetup_flightbatterystate(Picoc *pc) { if (FlightBatteryStateHandle() == NULL) ProgramFailNoParser(pc, "no flightbatterystate"); }
/* this is called when the header file is included */ void PlatformLibrarySetup_baroaltitude(Picoc *pc) { if (BaroAltitudeHandle() == NULL) ProgramFailNoParser(pc, "no baroaltitude"); }
/* this is called when the header file is included */ void PlatformLibrarySetup_gpsposition(Picoc *pc) { if (GPSPositionHandle() == NULL) ProgramFailNoParser(pc, "no gpsposition"); }