bool Parser::WeakSeparator(int n, int syFol, int repFol) { if (la->kind == n) {Get(); return true;} else if (StartOf(repFol)) {return false;} else { SynErr(n); while (!(StartOf(syFol) || StartOf(repFol) || StartOf(0))) { Get(); } return StartOf(syFol); } }
void Parser::ExpectWeak(int n, int follow) { if (la->kind == n) Get(); else { SynErr(n); while (!StartOf(follow)) Get(); } }
void Parser::ProcDecl() { wchar_t* name; Obj *obj; int adr; Expect(9); Ident(name); obj = tab->NewObj(name, proc, undef); obj->adr = gen->pc; if (coco_string_equal(name, L"Main")) gen->progStart = gen->pc; tab->OpenScope(); Expect(10); Expect(11); Expect(12); gen->Emit(ENTER, 0); adr = gen->pc - 2; while (StartOf(1)) { if (la->kind == 28 || la->kind == 29) { VarDecl(); } else { Stat(); } } Expect(13); gen->Emit(LEAVE); gen->Emit(RET); gen->Patch(adr, tab->topScope->nextAdr); tab->CloseScope(); }
bool FDefaultValueHelper::ParseVector2D(const FString& Source, FVector2D& OutVal) { const bool bHasWhitespace = HasWhitespaces(Source); const FString NoWhitespace = bHasWhitespace ? RemoveWhitespaces(Source) : FString(); const FString& ProperSource = bHasWhitespace ? NoWhitespace : Source; if(ProperSource.IsEmpty()) { return false; } const TCHAR* Start = StartOf(ProperSource); const TCHAR* FirstComma = FCString::Strstr( Start, TEXT(",") ); if(!FirstComma) { return false; } const TCHAR* End = EndOf(ProperSource); if( !IsStringValidFloat( Start, FirstComma ) || !IsStringValidFloat( FirstComma + 1, End ) ) { return false; } OutVal = FVector2D( FCString::Atof(Start), FCString::Atof(FirstComma + 1) ); return true; }
bool FDefaultValueHelper::IsStringValidVector(const FString& Source) { const TCHAR* Start = StartOf(Source); const TCHAR* FirstComma = FCString::Strstr( Start, TEXT(",") ); if(!FirstComma) { return false; } const TCHAR* SecondComma = FCString::Strstr( FirstComma + 1, TEXT(",") ); if(!SecondComma) { return false; } // there must be exactly 2 commas in the string if( FCString::Strstr( SecondComma + 1, TEXT(",") ) ) { return false; } const TCHAR* End = EndOf(Source); if( !IsStringValidFloat( Start, FirstComma ) || !IsStringValidFloat( FirstComma + 1, SecondComma ) || !IsStringValidFloat( SecondComma + 1, End ) ) { return false; } return true; }
bool FDefaultValueHelper::IsStringValidFloat(const FString& Source) { if(!Source.IsEmpty()) { return IsStringValidFloat( StartOf(Source), EndOf(Source) ); } return false; }
bool FDefaultValueHelper::IsStringValidInteger(const FString& Source) { if(!Source.IsEmpty()) { int32 Base; return IsStringValidInteger(StartOf(Source), EndOf(Source), Base); } return false; }
bool FDefaultValueHelper::ParseInt(const FString& Source, int32& OutVal) { int32 Base; if( !Source.IsEmpty() && IsStringValidInteger( StartOf(Source), EndOf(Source), Base ) ) { const bool bHasWhitespace = HasWhitespaces(Source); const FString NoWhitespace = bHasWhitespace ? RemoveWhitespaces(Source) : FString(); OutVal = FCString::Strtoi( bHasWhitespace ? *NoWhitespace : *Source , NULL, Base ); return true; } return false; }
bool FDefaultValueHelper::ParseColor(const FString& Source, FColor& OutVal) { const bool bHasWhitespace = HasWhitespaces(Source); const FString NoWhitespace = bHasWhitespace ? RemoveWhitespaces(Source) : FString(); const FString& ProperSource = bHasWhitespace ? NoWhitespace : Source; if(ProperSource.IsEmpty()) { return false; } const TCHAR* Start = StartOf(ProperSource); const TCHAR* FirstComma = FCString::Strstr( Start, TEXT(",") ); if(!FirstComma) { return false; } const TCHAR* SecondComma = FCString::Strstr( FirstComma + 1, TEXT(",") ); if(!SecondComma) { return false; } const TCHAR* ThirdComma = FCString::Strstr( SecondComma + 1, TEXT(",") ); const TCHAR* End = EndOf(ProperSource); if( ( NULL != ThirdComma ) && !IsStringValidInteger( ThirdComma + 1, End ) ) { return false; } if( !IsStringValidInteger( Start, FirstComma ) || !IsStringValidInteger( FirstComma + 1, SecondComma ) || !IsStringValidInteger( SecondComma + 1, ( NULL != ThirdComma ) ? ThirdComma : End ) ) { return false; } const float Alpha = ( NULL != ThirdComma ) ? FCString::Atoi( ThirdComma + 1 ) : 1.0f; OutVal = FColor( FCString::Atoi( Start ), FCString::Atoi( FirstComma + 1 ), FCString::Atoi( SecondComma + 1 ), Alpha ); return true; }
bool FDefaultValueHelper::IsStringValidLinearColor(const FString& Source) { if(Source.IsEmpty()) { return false; } const TCHAR* Start = StartOf(Source); const TCHAR* FirstComma = FCString::Strstr( Start, TEXT(",") ); if(!FirstComma) { return false; } const TCHAR* SecondComma = FCString::Strstr( FirstComma + 1, TEXT(",") ); if(!SecondComma) { return false; } const TCHAR* ThirdComma = FCString::Strstr( SecondComma + 1, TEXT(",") ); const TCHAR* End = EndOf(Source); if( ( NULL != ThirdComma ) && !IsStringValidFloat( ThirdComma + 1, End ) ) { return false; } if( !IsStringValidFloat( Start, FirstComma ) || !IsStringValidFloat( FirstComma + 1, SecondComma ) || !IsStringValidFloat( SecondComma + 1, ( NULL != ThirdComma ) ? ThirdComma : End ) ) { return false; } return true; }
void Parser::Stat() { int type; wchar_t* name; Obj *obj; int adr, adr2, loopstart; switch (la->kind) { case 1: { Ident(name); obj = tab->Find(name); if (la->kind == 17) { Get(); if (obj->kind != var) Err(L"cannot assign to procedure"); Expr(type); Expect(18); if (type != obj->type) Err(L"incompatible types"); if (obj->level == 0) gen->Emit(STOG, obj->adr); else gen->Emit(STO, obj->adr); } else if (la->kind == 10) { Get(); Expect(11); Expect(18); if (obj->kind != proc) Err(L"object is not a procedure"); gen->Emit(CALL, obj->adr); } else SynErr(36); break; } case 1: { Ident(name); obj = tab->Find(name); Expect(17); Expr(type); Expect(19); Expr(type2); Expect(20); Expr(type3); Expect(18); break; } case 21: { Get(); Expect(10); Expr(type); Expect(11); if (type != boolean) Err(L"boolean type expected"); gen->Emit(FJMP, 0); adr = gen->pc - 2; Stat(); if (la->kind == 22) { Get(); gen->Emit(JMP, 0); adr2 = gen->pc - 2; gen->Patch(adr, gen->pc); adr = adr2; Stat(); } gen->Patch(adr, gen->pc); break; } case 23: { Get(); loopstart = gen->pc; Expect(10); Expr(type); Expect(11); if (type != boolean) Err(L"boolean type expected"); gen->Emit(FJMP, 0); adr = gen->pc - 2; Stat(); gen->Emit(JMP, loopstart); gen->Patch(adr, gen->pc); break; } case 24: { Get(); loopstart = gen->pc; Expect(10); Expr(ty); Expect(18); Expr(type); Expect(18); Expr(ty); Expect(11); if (type != boolean) Err(L"boolean type expected"); gen->Emit(FJMP, 0); adr = gen->pc - 2; Stat(); break; } case 25: { Get(); Ident(name); Expect(18); obj = tab->Find(name); if (obj->type != integer) Err(L"integer type expected"); gen->Emit(READ); if (obj->level == 0) gen->Emit(STOG, obj->adr); else gen->Emit(STO, obj->adr); break; } case 26: { Get(); Expr(type); Expect(18); if (type != integer) Err(L"integer type expected"); gen->Emit(WRITE); break; } case 12: { Get(); while (StartOf(1)) { if (StartOf(2)) { Stat(); } else { VarDecl(); } } Expect(13); break; } default: SynErr(37); break; } }