static void ram_to_rom(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { (void) ReturnValue; (void) NumArgs; (void) Param; //delete flash page PlatformPrintf(Parser->pc, "erasing flash\n"); if (!flashErase(sector)) { //write data to flash PlatformPrintf(Parser->pc, "writing to flash\n"); if (!flashWrite((uint32_t *) flash_base, script_buffer, strlen(script_buffer) + 1)) { PlatformPrintf(Parser->pc, "done!\n"); } else { PlatformPrintf(Parser->pc, "!! writing error !!\n"); } } else { PlatformPrintf(Parser->pc, "!! flash erasing error !!\n"); } }
/* before we run a statement, check if there's anything we have to do with the debugger here */ void DebugCheckStatement(struct ParseState *Parser) { int DoBreak = FALSE; int AddAt; Picoc *pc = Parser->pc; /* has the user manually pressed break? */ if (pc->DebugManualBreak) { PlatformPrintf(pc->CStdOut, "break\n"); DoBreak = TRUE; pc->DebugManualBreak = FALSE; } /* is this a breakpoint location? */ if (Parser->pc->BreakpointCount != 0 && DebugTableSearchBreakpoint(Parser, &AddAt) != NULL) DoBreak = TRUE; /* handle a break */ if (DoBreak) { PlatformPrintf(pc->CStdOut, "Handling a break\n"); PicocParseInteractiveNoStartPrompt(pc, FALSE); } }
static void secret_function(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { (void) ReturnValue; (void) NumArgs; (void) Param; char * p = script_buffer; size_t counter = 0; //self while loop with reading lines.... until another secret sequence or eof PlatformPrintf(Parser->pc, "disabling shell and starting write raw data to buffer\n"); char c = PlatformGetCharacter(Parser->pc); while ((c != 0x3) && (c != 0x1a)) { *p = c; p++; counter++; c = PlatformGetCharacter(Parser->pc); } *p = 0; PlatformPrintf(Parser->pc, "memory usage: %d percent (%d of %d bytes)\n", 100*counter / sizeof(script_buffer), counter, sizeof(script_buffer)); PlatformPrintf(Parser->pc, "data reading finished, returning to shell\n"); }
/* like ProgramFail() but gives descriptive error messages for assignment */ void AssignFail(struct ParseState *Parser, const char *Format, struct ValueType *Type1, struct ValueType *Type2, int Num1, int Num2, const char *FuncName, int ParamNo) { PlatformErrorPrefix(Parser); PlatformPrintf("no puedo %s ", (FuncName == NULL) ? "asignar" : "fijar"); if (Type1 != NULL) PlatformPrintf(Format, Type1, Type2); else PlatformPrintf(Format, Num1, Num2); if (FuncName != NULL) PlatformPrintf(" in argument %d of call to %s()", ParamNo, FuncName); ProgramFail(NULL, ""); }
/* like ProgramFail() but gives descriptive error messages for assignment */ void AssignFail(struct ParseState *Parser, const char *Format, struct ValueType *Type1, struct ValueType *Type2, int Num1, int Num2, const char *FuncName, int ParamNo) { IOFILE *Stream = Parser->pc->CStdOut; PrintSourceTextErrorLine(Parser->pc->CStdOut, Parser->FileName, Parser->SourceText, Parser->Line, Parser->CharacterPos); PlatformPrintf(Stream, "can't %s ", (FuncName == NULL) ? "assign" : "set"); if (Type1 != NULL) PlatformPrintf(Stream, Format, Type1, Type2); else PlatformPrintf(Stream, Format, Num1, Num2); if (FuncName != NULL) PlatformPrintf(Stream, " in argument %d of call to %s()", ParamNo, FuncName); ProgramFail(Parser, NULL, ""); }
static void read_ram(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { (void) ReturnValue; (void) NumArgs; (void) Param; PlatformPrintf(Parser->pc, "%s", script_buffer); }
static void read_flash(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { (void) ReturnValue; (void) NumArgs; (void) Param; PlatformPrintf(Parser->pc, "%s", flash_base); }
/* exit with a message, when we're not parsing a program */ void ProgramFailNoParser(Picoc *pc, const char *Message, ...) { va_list Args; va_start(Args, Message); PlatformVPrintf(pc->CStdOut, Message, Args); va_end(Args); PlatformPrintf(pc->CStdOut, "\n"); PlatformExit(pc, 1); }
/* exit with a message */ void ProgramFail(struct ParseState *Parser, const char *Message, ...) { va_list Args; PlatformErrorPrefix(Parser); va_start(Args, Message); PlatformVPrintf(Message, Args); va_end(Args); PlatformPrintf("\n"); PlatformExit(1); }
/* exit with a message */ void ProgramFail(struct ParseState *Parser, const char *Message, ...) { va_list Args; PrintSourceTextErrorLine(Parser->pc->CStdOut, Parser->FileName, Parser->SourceText, Parser->Line, Parser->CharacterPos); va_start(Args, Message); PlatformVPrintf(Parser->pc->CStdOut, Message, Args); va_end(Args); PlatformPrintf(Parser->pc->CStdOut, "\n"); PlatformExit(Parser->pc, 1); }
/* exit lexing with a message */ void LexFail(struct LexState *Lexer, const char *Message, ...) { va_list Args; PrintSourceTextErrorLine(Lexer->FileName, Lexer->SourceText, Lexer->Line, Lexer->CharacterPos); va_start(Args, Message); PlatformVPrintf(Message, Args); va_end(Args); PlatformPrintf("\n"); PlatformExit(1); }
static void use_flash(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { (void) ReturnValue; (void) NumArgs; (void) Param; ram_enable(false); PlatformPrintf(Parser->pc, "switched to flash"); }
/* parse interactively */ void PicocParseInteractive() { struct ParseState Parser; enum ParseResult Ok; PlatformPrintf(INTERACTIVE_PROMPT_START); LexInitParser(&Parser, NULL, NULL, StrEmpty, TRUE); // PicocPlatformSetExitPoint(); LexInteractiveClear(&Parser); do { LexInteractiveStatementPrompt(); Ok = ParseStatement(&Parser, TRUE); LexInteractiveCompleted(&Parser); } while (Ok == ParseResultOk); if (Ok == ParseResultError) ProgramFail(&Parser, "parse error"); PlatformPrintf("\n"); }
void PrintSourceTextErrorLine(const char *FileName, const char *SourceText, int Line, int CharacterPos) { int LineCount; const char *LinePos; const char *CPos; int CCount; PlatformSourceError(FileName, SourceText, Line, CharacterPos); return; if (SourceText != NULL) { /* find the source line */ for (LinePos = SourceText, LineCount = 1; *LinePos != '\0' && LineCount < Line; LinePos++) { if (*LinePos == '\n') LineCount++; } /* display the line */ for (CPos = LinePos; *CPos != '\n' && *CPos != '\0'; CPos++) PrintCh(*CPos, CStdOut); PrintCh('\n', CStdOut); /* display the error position */ for (CPos = LinePos, CCount = 0; *CPos != '\n' && *CPos != '\0' && (CCount < CharacterPos || *CPos == ' '); CPos++, CCount++) { if (*CPos == '\t') PrintCh('\t', CStdOut); else PrintCh(' ', CStdOut); } } else { /* assume we're in interactive mode - try to make the arrow match up with the input text */ for (CCount = 0; CCount < CharacterPos + strlen(INTERACTIVE_PROMPT_STATEMENT); CCount++) PrintCh(' ', CStdOut); } PlatformPrintf("^\n%s:%d: ", FileName, Line, CharacterPos); }
/* parse interactively */ void PicocParseInteractiveNoStartPrompt(Picoc *pc, int EnableDebugger) { struct ParseState Parser; enum ParseResult Ok; LexInitParser(&Parser, pc, NULL, NULL, pc->StrEmpty, TRUE, EnableDebugger); LexInteractiveClear(pc, &Parser); do { LexInteractiveStatementPrompt(pc); Ok = ParseStatement(&Parser, TRUE); LexInteractiveCompleted(pc, &Parser); } while (Ok == ParseResultOk); if (Ok == ParseResultError) ProgramFail(&Parser, "parse error"); PlatformPrintf(pc, "\n"); }
/* parse a statement */ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon) { struct Value *CValue; struct Value *LexerValue; struct Value *VarValue; int Condition; struct ParseState PreState; enum LexToken Token; /* if we're debugging, check for a breakpoint */ if (Parser->DebugMode && Parser->Mode == RunModeRun) DebugCheckStatement(Parser); /* take note of where we are and then grab a token to see what statement we have */ ParserCopy(&PreState, Parser); Token = LexGetToken(Parser, &LexerValue, TRUE); switch (Token) { case TokenEOF: return ParseResultEOF; case TokenIdentifier: /* might be a typedef-typed variable declaration or it might be an expression */ if (VariableDefined(Parser->pc, LexerValue->Val->Identifier)) { VariableGet(Parser->pc, Parser, LexerValue->Val->Identifier, &VarValue); if (VarValue->Typ->Base == Type_Type) { *Parser = PreState; ParseDeclaration(Parser, Token); break; } } else { /* it might be a goto label */ enum LexToken NextToken = LexGetToken(Parser, NULL, FALSE); if (NextToken == TokenColon) { /* declare the identifier as a goto label */ LexGetToken(Parser, NULL, TRUE); if (Parser->Mode == RunModeGoto && LexerValue->Val->Identifier == Parser->SearchGotoLabel) Parser->Mode = RunModeRun; CheckTrailingSemicolon = FALSE; break; } #ifdef FEATURE_AUTO_DECLARE_VARIABLES else /* new_identifier = something */ { /* try to guess type and declare the variable based on assigned value */ if (NextToken == TokenAssign && !VariableDefinedAndOutOfScope(Parser->pc, LexerValue->Val->Identifier)) { if (Parser->Mode == RunModeRun) { struct Value *CValue; char* Identifier = LexerValue->Val->Identifier; LexGetToken(Parser, NULL, TRUE); if (!ExpressionParse(Parser, &CValue)) { ProgramFail(Parser, "expected: expression"); } #if 0 PRINT_SOURCE_POS; PlatformPrintf(Parser->pc->CStdOut, "%t %s = %d;\n", CValue->Typ, Identifier, CValue->Val->Integer); printf("%d\n", VariableDefined(Parser->pc, Identifier)); #endif VariableDefine(Parser->pc, Parser, Identifier, CValue, CValue->Typ, TRUE); break; } } } #endif } /* else fallthrough to expression */ /* no break */ case TokenAsterisk: case TokenAmpersand: case TokenIncrement: case TokenDecrement: case TokenOpenBracket: *Parser = PreState; ExpressionParse(Parser, &CValue); if (Parser->Mode == RunModeRun) VariableStackPop(Parser, CValue); break; case TokenLeftBrace: ParseBlock(Parser, FALSE, TRUE); CheckTrailingSemicolon = FALSE; break; case TokenIf: if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) ProgramFail(Parser, "'(' expected"); Condition = ExpressionParseInt(Parser) != 0; if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) ProgramFail(Parser, "')' expected"); if (ParseStatementMaybeRun(Parser, Condition, TRUE) != ParseResultOk) ProgramFail(Parser, "statement expected"); if (LexGetToken(Parser, NULL, FALSE) == TokenElse) { LexGetToken(Parser, NULL, TRUE); if (ParseStatementMaybeRun(Parser, !Condition, TRUE) != ParseResultOk) ProgramFail(Parser, "statement expected"); } CheckTrailingSemicolon = FALSE; break; case TokenWhile: { struct ParseState PreConditional; enum RunMode PreMode = Parser->Mode; if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) ProgramFail(Parser, "'(' expected"); ParserCopyPos(&PreConditional, Parser); do { ParserCopyPos(Parser, &PreConditional); Condition = ExpressionParseInt(Parser) != 0; if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) ProgramFail(Parser, "')' expected"); if (ParseStatementMaybeRun(Parser, Condition, TRUE) != ParseResultOk) ProgramFail(Parser, "statement expected"); if (Parser->Mode == RunModeContinue) Parser->Mode = PreMode; } while (Parser->Mode == RunModeRun && Condition); if (Parser->Mode == RunModeBreak) Parser->Mode = PreMode; CheckTrailingSemicolon = FALSE; } break; case TokenDo: { struct ParseState PreStatement; enum RunMode PreMode = Parser->Mode; ParserCopyPos(&PreStatement, Parser); do { ParserCopyPos(Parser, &PreStatement); if (ParseStatement(Parser, TRUE) != ParseResultOk) ProgramFail(Parser, "statement expected"); if (Parser->Mode == RunModeContinue) Parser->Mode = PreMode; if (LexGetToken(Parser, NULL, TRUE) != TokenWhile) ProgramFail(Parser, "'while' expected"); if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) ProgramFail(Parser, "'(' expected"); Condition = ExpressionParseInt(Parser) != 0; if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) ProgramFail(Parser, "')' expected"); } while (Condition && Parser->Mode == RunModeRun); if (Parser->Mode == RunModeBreak) Parser->Mode = PreMode; } break; case TokenFor: ParseFor(Parser); CheckTrailingSemicolon = FALSE; break; case TokenSemicolon: CheckTrailingSemicolon = FALSE; break; case TokenIntType: case TokenShortType: case TokenCharType: case TokenLongType: case TokenFloatType: case TokenDoubleType: case TokenVoidType: case TokenStructType: case TokenUnionType: case TokenEnumType: case TokenSignedType: case TokenUnsignedType: case TokenStaticType: case TokenAutoType: case TokenRegisterType: case TokenExternType: *Parser = PreState; CheckTrailingSemicolon = ParseDeclaration(Parser, Token); break; case TokenHashDefine: ParseMacroDefinition(Parser); CheckTrailingSemicolon = FALSE; break; #ifndef NO_HASH_INCLUDE case TokenHashInclude: if (LexGetToken(Parser, &LexerValue, TRUE) != TokenStringConstant) ProgramFail(Parser, "\"filename.h\" expected"); IncludeFile(Parser->pc, (char *)LexerValue->Val->Pointer); CheckTrailingSemicolon = FALSE; break; #endif case TokenSwitch: if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) ProgramFail(Parser, "'(' expected"); Condition = (int) ExpressionParseInt(Parser); if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) ProgramFail(Parser, "')' expected"); if (LexGetToken(Parser, NULL, FALSE) != TokenLeftBrace) ProgramFail(Parser, "'{' expected"); { /* new block so we can store parser state */ enum RunMode OldMode = Parser->Mode; int64_t OldSearchLabel = Parser->SearchLabel; Parser->Mode = RunModeCaseSearch; Parser->SearchLabel = Condition; ParseBlock(Parser, TRUE, (OldMode != RunModeSkip) && (OldMode != RunModeReturn)); if (Parser->Mode != RunModeReturn) Parser->Mode = OldMode; Parser->SearchLabel = OldSearchLabel; } CheckTrailingSemicolon = FALSE; break; case TokenCase: if (Parser->Mode == RunModeCaseSearch) { Parser->Mode = RunModeRun; Condition = (int) ExpressionParseInt(Parser); Parser->Mode = RunModeCaseSearch; } else Condition = (int) ExpressionParseInt(Parser); if (LexGetToken(Parser, NULL, TRUE) != TokenColon) ProgramFail(Parser, "':' expected"); if (Parser->Mode == RunModeCaseSearch && Condition == Parser->SearchLabel) Parser->Mode = RunModeRun; CheckTrailingSemicolon = FALSE; break; case TokenDefault: if (LexGetToken(Parser, NULL, TRUE) != TokenColon) ProgramFail(Parser, "':' expected"); if (Parser->Mode == RunModeCaseSearch) Parser->Mode = RunModeRun; CheckTrailingSemicolon = FALSE; break; case TokenBreak: if (Parser->Mode == RunModeRun) Parser->Mode = RunModeBreak; break; case TokenContinue: if (Parser->Mode == RunModeRun) Parser->Mode = RunModeContinue; break; case TokenReturn: if (Parser->Mode == RunModeRun) { if (!Parser->pc->TopStackFrame || Parser->pc->TopStackFrame->ReturnValue->Typ->Base != TypeVoid) { if (!ExpressionParse(Parser, &CValue)) ProgramFail(Parser, "value required in return"); if (!Parser->pc->TopStackFrame) /* return from top-level program? */ PlatformExit(Parser->pc, (int)ExpressionCoerceLong(CValue)); else ExpressionAssign(Parser, Parser->pc->TopStackFrame->ReturnValue, CValue, TRUE, NULL, 0, FALSE); VariableStackPop(Parser, CValue); } else { if (ExpressionParse(Parser, &CValue)) ProgramFail(Parser, "value in return from a void function"); } Parser->Mode = RunModeReturn; } else ExpressionParse(Parser, &CValue); break; case TokenTypedef: ParseTypedef(Parser); break; case TokenGoto: if (LexGetToken(Parser, &LexerValue, TRUE) != TokenIdentifier) ProgramFail(Parser, "identifier expected"); if (Parser->Mode == RunModeRun) { /* start scanning for the goto label */ Parser->SearchGotoLabel = LexerValue->Val->Identifier; Parser->Mode = RunModeGoto; } break; case TokenDelete: { /* try it as a function or variable name to delete */ if (LexGetToken(Parser, &LexerValue, TRUE) != TokenIdentifier) ProgramFail(Parser, "identifier expected"); if (Parser->Mode == RunModeRun) { /* delete this variable or function */ CValue = TableDelete(Parser->pc, &Parser->pc->GlobalTable, LexerValue->Val->Identifier); if (CValue == NULL) ProgramFail(Parser, "'%s' is not defined", LexerValue->Val->Identifier); VariableFree(Parser->pc, CValue); } break; } default: *Parser = PreState; return ParseResultError; } if (CheckTrailingSemicolon) { if (LexGetToken(Parser, NULL, TRUE) != TokenSemicolon) ProgramFail(Parser, "';' expected"); } return ParseResultOk; }
/* parse interactively, showing a startup message */ void PicocParseInteractive(Picoc *pc) { PlatformPrintf(pc->CStdOut, INTERACTIVE_PROMPT_START); PicocParseInteractiveNoStartPrompt(pc, TRUE); }
/* parse interactively, showing a startup message */ void PicocParseInteractive() { PlatformPrintf(INTERACTIVE_PROMPT_START); PicocParseInteractiveNoStartPrompt(TRUE); }
/* print a type to a stream without using printf/sprintf */ void PrintType(struct ValueType *Typ, Picoc* pc) { switch (Typ->Base) { case TypeVoid: PlatformPrintf(pc, "void"); break; case TypeInt: PlatformPrintf(pc, "int"); break; case TypeShort: PlatformPrintf(pc, "short"); break; case TypeChar: PlatformPrintf(pc, "char"); break; case TypeLong: PlatformPrintf(pc, "long"); break; case TypeUnsignedInt: PlatformPrintf(pc, "unsigned int"); break; case TypeUnsignedShort: PlatformPrintf(pc, "unsigned short"); break; case TypeUnsignedLong: PlatformPrintf(pc, "unsigned long"); break; case TypeUnsignedChar: PlatformPrintf(pc, "unsigned char"); break; #ifndef NO_FP case TypeFP: PlatformPrintf(pc, "double"); break; #endif case TypeFunction: PlatformPrintf(pc, "function"); break; case TypeMacro: PlatformPrintf(pc, "macro"); break; case TypePointer: if (Typ->FromType) PrintType(Typ->FromType, pc); PlatformPrintf(pc, "*"); break; case TypeArray: PrintType(Typ->FromType, pc); PlatformPrintf(pc, "["); if (Typ->ArraySize != 0) PlatformPrintf(pc, "%d", Typ->ArraySize); PlatformPrintf(pc, "]"); break; case TypeStruct: PlatformPrintf(pc, "struct "); PlatformPrintf(pc, Typ->Identifier); break; case TypeUnion: PlatformPrintf(pc, "union "); PlatformPrintf(pc, Typ->Identifier); break; case TypeEnum: PlatformPrintf(pc, "enum "); PlatformPrintf(pc, Typ->Identifier); break; case TypeGotoLabel: PlatformPrintf(pc, "goto label "); break; case Type_Type: PlatformPrintf(pc, "type "); break; } }