#include "KSGSBefehl.h" #include "../Error/Error.h" #include "../Leser/KSGSLeser.h" #include "../Leser/KSGSCompile.h" #include "../Main/KSGScriptObj.h" #include "KSGSKlasse.h" #include "../Klassen/KSGSInt.h" #include "../Klassen/KSGSDouble.h" #include "../Klassen/KSGSBool.h" #include "../Klassen/KSGSText.h" #include "../Klassen/KSGSTyp.h" using namespace KSGScript; // Befehls Strukturen KSGSBefehlVariable::KSGSBefehlVariable( Text *txt, KSGSCompKlassTable *zKT, KSGSCompFuncTable *zFT, KSGSCompVarTable *zVT, const char *klassName, const char *funktionName, int *typId, bool *ok ) { txt->setSuchGrenzen( '(', ')' ); removeKlammer( txt ); Text name = txt->getText(); txt->release(); *ok = 0; if( !funktionName && !klassName ) return; KSGSCompFuncTable *zLFT = zFT; KSGSCompVarTable *zLVT = zVT; if( klassName ) { if( !zKT->hat( klassName ) ) return; zLFT = &zKT->get( klassName )->funcs; zLVT = &zKT->get( klassName )->vars; } if( *typId >= 0 ) { // Variable gehört zu einem anderen Zeichnung if( !zKT->hat( *typId ) || !zKT->get( *typId )->vars.hat( name ) ) return; varId = zKT->get( *typId )->vars.get( name )->id; varSichtbar = zKT->get( *typId )->vars.get( name )->sichtbar; *typId = zKT->get( *typId )->vars.get( name )->typ; } else { // Variable gehört zu diesem Zeichnung if( !zLFT->hat( funktionName ) ) return; if( zLFT->get( funktionName )->vars.hat( name ) ) { varId = zLFT->get( funktionName )->vars.get( name )->id; *typId = zLFT->get( funktionName )->vars.get( name )->typ; varSichtbar = zLFT->get( funktionName )->vars.get( name )->sichtbar; } else if( zLVT->hat( name ) ) { varId = zLVT->get( name )->id; *typId = zLVT->get( name )->typ; varSichtbar = zLVT->get( name )->sichtbar; } else if( zVT->hat( name ) ) { varId = zVT->get( name )->id; *typId = zVT->get( name )->typ; varSichtbar = zVT->get( name )->sichtbar; } else return; } *ok = 1; } KSGSBefehlFunktion::KSGSBefehlFunktion( KSGScriptObj *zObj, Text *txt, KSGSLeseDebug *dbg, KSGSCompKlassTable *zKT, KSGSCompFuncTable *zFT, KSGSCompVarTable *zVT, const char *klassName, const char *funktionName, int *typId, bool *ok ) { *ok = 0; int retTyp = -1; txt->setSuchGrenzen( '(', ')' ); removeKlammer( txt ); if( !txt->hat( '(' ) || ( !klassName && !funktionName ) ) { txt->release(); return; } Text *name = txt->getTeilText( 0, txt->positionVon( '(' ) ); Text *parameter = txt->getTeilText( txt->positionVon( '(' ) ); txt->release(); name->setSuchGrenzen( '(', ')' ); removeKlammer( name ); parameter->setSuchGrenzen( '(', ')' ); removeKlammer( parameter ); KSGSCompFuncTable *zLFT = zFT; KSGSCompVarTable *zLVT = zVT; if( klassName ) { if( !zKT->hat( klassName ) ) { name->release(); parameter->release(); return; } zLFT = &zKT->get( klassName )->funcs; zLVT = &zKT->get( klassName )->vars; } if( *typId >= 0 ) { // Funktion gehört zu anderem Zeichnung if( !zKT->hat( *typId ) ) { name->release(); parameter->release(); return; } zLFT = &zKT->get( *typId )->funcs; zLVT = &zKT->get( *typId )->vars; } Array< int > *paramTyps = 0; bool noWarn = 0; if( zLFT->hat( *name ) ) { funcId = zLFT->get( *name )->id; if( funcId == 0 && name->istGleich( "Rückruf" ) ) noWarn = 1; funkSichtbar = zLFT->get( *name )->sichtbar; paramTyps = &zLFT->get( *name )->parameterTyp; retTyp = zLFT->get( *name )->typ; } else if( *typId < 0 && zFT->hat( *name ) ) { funcId = zFT->get( *name )->id; if( funcId == 0 && name->istGleich( "Rückruf" ) ) noWarn = 1; funkSichtbar = zFT->get( *name )->sichtbar; paramTyps = &zFT->get( *name )->parameterTyp; retTyp = zFT->get( *name )->typ; } else { name->release(); parameter->release(); return; } // Parameter int ptAnz = paramTyps->getEintragAnzahl(); int pAnz = parameter->anzahlVon( ',' ) + 1; if( !parameter->getLength() ) pAnz = 0; if( ptAnz != pAnz ) { if( !noWarn ) error( 14, { dbg->datei, Text() += dbg->zeile }, zObj ); ptAnz = ptAnz < pAnz ? pAnz : ptAnz; } for( int i = 0; i < ptAnz; i++ ) { // für jeden Parameter int beg = 0; int end = parameter->getLength(); if( i > 0 ) beg = parameter->positionVon( ',', i - 1 ) + 1; if( i < ptAnz - 1 ) end = parameter->positionVon( ',', i ); Text *p = parameter->getTeilText( beg, end ); bool b = 0; int pTyp = -1; KSGSBefehlParameter *param = new KSGSBefehlParameter( zObj, p, dbg, zKT, zFT, zVT, klassName, funktionName, &pTyp, &b ); if( !b ) { name->release(); parameter->release(); delete param; return; } this->parameter.add( param ); } name->release(); parameter->release(); *typId = retTyp; *ok = 1; } KSGSBefehlFunktion::~KSGSBefehlFunktion() { int anz = parameter.getEintragAnzahl(); for( int i = 0; i < anz; i++ ) delete parameter.get( i ); } KSGSBefehlMember::KSGSBefehlMember( KSGScriptObj *zObj, Text *txt, KSGSLeseDebug *dbg, KSGSCompKlassTable *zKT, KSGSCompFuncTable *zFT, KSGSCompVarTable *zVT, const char *klassName, const char *funktionName, int *typId, bool *ok ) { *ok = 0; bef = 0; funk = 0; var = 0; txt->setSuchGrenzen( '(', ')' ); removeKlammer( txt ); Text abschnitt = txt->getText(); abschnitt.setSuchGrenzen( '(', ')' ); txt->release(); if( hatOperator( &abschnitt ) >= 0 ) { // Befehl typ = BEFEHL; KSGSLeseBefehl *tmp = new KSGSLeseBefehl(); tmp->befehl = abschnitt.getText(); tmp->befehl.setSuchGrenzen( '(', ')' ); removeKlammer( &tmp->befehl ); tmp->debug.datei = dbg->datei.getText(); tmp->debug.zeile = dbg->zeile; tmp->typ = 0; bef = new KSGSOperatorBefehl( zObj, tmp, zKT, zFT, zVT, klassName, funktionName ); delete tmp; if( bef->hatFehler() ) return; *typId = bef->getReturnTyp(); } else if( abschnitt.hat( '(' ) ) { // Funktionsaufruf typ = FUNKTION; bool b = 0; funk = new KSGSBefehlFunktion( zObj, abschnitt.getThis(), dbg, zKT, zFT, zVT, klassName, funktionName, typId, &b ); if( !b ) return; } else { // Variable typ = VARIABLE; bool b = 0; var = new KSGSBefehlVariable( abschnitt.getThis(), zKT, zFT, zVT, klassName, funktionName, typId, &b ); if( !b ) return; } *ok = 1; } KSGSBefehlMember::~KSGSBefehlMember() { if( bef ) bef->release(); delete funk; delete var; } KSGSBefehlParameter::KSGSBefehlParameter( KSGScriptObj *zObj, Text *txt, KSGSLeseDebug *dbg, KSGSCompKlassTable *zKT, KSGSCompFuncTable *zFT, KSGSCompVarTable *zVT, const char *klassName, const char *funktionName, int *typId, bool *ok ) { *typId = -1; *ok = 0; int retTyp = -1; Text param = txt->getText(); param.setSuchGrenzen( '(', ')' ); removeKlammer( ¶m ); txt->release(); if( !param.getLength() || ( !klassName && !funktionName ) ) return; if( param.getLength() > 2 && param[ 0 ] == '0' && param[ 1 ] == 'x' ) { // Hex Zahl typ = WERT; wert = (int)param; *typId = zKT->get( "int" )->id; } else if( param.getLength() == 3 && param[ 0 ] == '\'' && param[ 2 ] == '\'' ) { // Char typ = WERT; wert = (int)param[ 1 ]; *typId = zKT->get( "int" )->id; } else if( param.getLength() > 1 && param[ 0 ] == '"' && param[ param.getLength() - 1 ] == '"' ) { // Text typ = WERT; int anz = param.getLength(); bool backSlash = 0; for( int i = 0; i < anz; i++ ) { if( param[ i ] == '\\' ) { if( backSlash ) { wert.append( '\\' ); backSlash = 0; } else backSlash = 1; } else if( backSlash ) { switch( param[ i ] ) { case 'n': wert.append( '\n' ); break; case 'r': wert.append( '\r' ); break; case 't': wert.append( '\t' ); break; case '"': wert.append( '"' ); break; case '0': wert.append( '\0' ); break; case '1': wert.append( '\1' ); break; case '2': wert.append( '\2' ); break; case '3': wert.append( '\3' ); break; case '4': wert.append( '\4' ); break; case '5': wert.append( '\5' ); break; case '6': wert.append( '\6' ); break; case '7': wert.append( '\7' ); break; case '8': wert.append( '\x8' ); break; case '9': wert.append( '\x9' ); break; } backSlash = 0; } else wert.append( param[ i ] ); } *typId = zKT->get( "Text" )->id; } else if( param.istGleich( "true" ) ) { // True typ = WERT; wert = "true"; *typId = zKT->get( "Text" )->id; } else if( param.istGleich( "false" ) ) { // False typ = WERT; wert = "false"; *typId = zKT->get( "Text" )->id; } else { bool num = 1; bool p = 0; bool m = 0; for( int i = 0; i < param.getLength(); i++ ) { num &= ( param[ i ] >= '0' && param[ i ] <= '9' ) || param[ i ] == '.' || param[ i ] == '-'; if( param[ i ] == '.' ) { if( p ) num = 0; p = 1; } if( param[ i ] == '-' ) { if( m ) num = 0; m = 1; } } if( num ) { // Zahl typ = WERT; if( !p ) { wert = (int)param; *typId = KSGS_INT; } else { wert = (double)param; *typId = KSGS_DOUBLE; } } else { // Objekt typ = OBJEKT; if( hatOperator( ¶m ) >= 0 ) { // Befehl bool b = 0; KSGSBefehlMember *obj = new KSGSBefehlMember( zObj, param.getThis(), dbg, zKT, zFT, zVT, klassName, funktionName, typId, &b ); if( !b ) { delete obj; return; } objekt.add( obj ); } else { // Zeichnung Kette int abschnittAnz = param.anzahlVon( '.' ) + 1; int *abschnittEnde = new int[ abschnittAnz ]; for( int i = 0; i < abschnittAnz - 1; i++ ) abschnittEnde[ i ] = param.positionVon( '.', i ); abschnittEnde[ abschnittAnz - 1 ] = param.getLength(); for( int i = 0; i < abschnittAnz; i++ ) { int beg = 0; if( i > 0 ) beg = abschnittEnde[ i - 1 ] + 1; int end = abschnittEnde[ i ]; Text *abschnitt = param.getTeilText( beg, end ); bool b = 0; KSGSBefehlMember *mem = new KSGSBefehlMember( zObj, abschnitt, dbg, zKT, zFT, zVT, klassName, funktionName, typId, &b ); if( !b ) { delete mem; delete[] abschnittEnde; return; } objekt.add( mem ); } delete[] abschnittEnde; } } } *ok = 1; } KSGSBefehlParameter::~KSGSBefehlParameter() { int anz = objekt.getEintragAnzahl(); for( int i = 0; i < anz; i++ ) delete objekt.get( i ); } KSGSBefehlErstell::KSGSBefehlErstell( KSGScriptObj *zObj, Text *txt, KSGSLeseDebug *dbg, KSGSCompKlassTable *zKT, KSGSCompFuncTable *zFT, KSGSCompVarTable *zVT, const char *klassName, const char *funktionName, bool *ok ) { param = 0; konstruktor = 0; *ok = 0; Text text = txt->getText(); text.setSuchGrenzen( '(', ')' ); removeKlammer( &text ); txt->release(); if( !text.getLength() || ( !klassName && !funktionName ) ) return; KSGSCompFuncTable *zLFT = zFT; if( klassName ) zLFT = &zKT->get( klassName )->funcs; Text *typ = text.getTeilText( 0, text.positionVon( ' ' ) ); typ->setSuchGrenzen( '(', ')' ); removeKlammer( typ ); if( !zKT->hat( (char*)*typ ) ) { typ->release(); return; } typId = zKT->get( (char*)*typ )->id; char endC = 0; if( text.hat( '(' ) ) { endC = '('; Text *name = text.getTeilText( text.positionVon( ' ' ) + 1, text.positionVon( '(' ) ); konstruktor = 1; Text befehl = name->getText(); name->release(); befehl += "."; befehl += typ->getText(); befehl += &text[ text.positionVon( '(' ) ]; bool b = 0; int pTyp = -1; param = new KSGSBefehlParameter( zObj, befehl.getThis(), dbg, zKT, zFT, zVT, klassName, funktionName, &pTyp, &b ); if( !b ) { typ->release(); return; } } else if( text.hat( '=' ) ) { endC = '='; konstruktor = 0; Text *p = text.getTeilText( text.positionVon( '=' ) + 1 ); p->setSuchGrenzen( '(', ')' ); removeKlammer( p ); bool b = 0; int pTyp = -1; param = new KSGSBefehlParameter( zObj, p, dbg, zKT, zFT, zVT, klassName, funktionName, &pTyp, &b ); if( !b ) { typ->release(); return; } } typ->release(); Text *name = text.getTeilText( text.positionVon( ' ' ) + 1, endC ? text.positionVon( endC ) : text.getLength() ); name->setSuchGrenzen( '(', ')' ); removeKlammer( name ); if( zLFT->get( funktionName )->vars.hat( *name ) ) { name->release(); return; } zLFT->get( funktionName )->vars.addVariable( *name, new KSGSCompileVariable( typId, 3 ) ); id = zLFT->get( funktionName )->vars.get( *name )->id; name->release(); *ok = 1; } KSGSBefehlErstell::~KSGSBefehlErstell() { delete param; } // Inhalt der KSGSBefehl Klasse aus KSGSBefehl.h // Konstruktor KSGSBefehl::KSGSBefehl( Typ typ ) { this->typ = typ; fehler = 0; returnTyp = -1; ref = 1; } // Destruktor KSGSBefehl::~KSGSBefehl() { } // constant KSGSVariable *KSGSBefehl::ausführen( KSGScriptObj *zObj, KSGSFunktionInstanz *zFI, KSGSKlasseInstanz *zKI ) const { return 0; } bool KSGSBefehl::hatFehler() const { return fehler; } int KSGSBefehl::getReturnTyp() const { return returnTyp; } bool KSGSBefehl::istTyp( Typ t ) const { return typ == t; } // Reference Counting KSGSBefehl *KSGSBefehl::getThis() { ref++; return this; } KSGSBefehl *KSGSBefehl::release() { ref--; if( !ref ) delete this; return 0; } // static KSGSVariable *KSGSBefehl::prozessVariable( KSGSVariable *zVorObj, KSGSBefehlVariable *zVar, KSGScriptObj *zObj, KSGSFunktionInstanz *zFI, KSGSKlasseInstanz *zKI ) { if( !zVar ) { error( 22, {}, zObj ); return 0; } switch( zVar->varSichtbar ) { case 0: // public if( !zVorObj ) return zObj->getVariable( zVar->varId ); break; case 1: // public in Klasse if( zVorObj ) return zVorObj->getVariable( zVar->varId, 0 ); else if( zKI ) return zKI->getVariable( zVar->varId, 1 ); break; case 2: // privat in Klasse if( zKI && !zVorObj ) return zKI->getVariable( zVar->varId, 1 ); break; case 3: // lokal in Funktion if( !zVorObj && zFI ) return zFI->getVariable( zVar->varId ); break; } error( 22, {}, zObj ); return 0; } KSGSVariable *KSGSBefehl::prozessFunktion( KSGSVariable *zVorObj, KSGSBefehlFunktion *zFunk, KSGScriptObj *zObj, KSGSFunktionInstanz *zFI, KSGSKlasseInstanz *zKI ) { if( !zFunk ) { error( 22, {}, zObj ); return 0; } RCArray< KSGSVariable > *parameter = new RCArray< KSGSVariable >(); int pAnz = zFunk->parameter.getEintragAnzahl(); for( int i = 0; i < pAnz; i++ ) parameter->set( prozessParameter( zFunk->parameter.get( i ), zObj, zFI, zKI ), i ); switch( zFunk->funkSichtbar ) { case 0: // public if( !zVorObj ) return zObj->startFunktion( zFunk->funcId, parameter ); break; case 1: // public in Klasse if( zVorObj ) return zVorObj->startFunktion( zFunk->funcId, 0, parameter ); else if( zKI ) return zKI->startFunktion( zFunk->funcId, 1, parameter ); break; case 2: // privat in Klasse if( zKI && !zVorObj ) return zKI->startFunktion( zFunk->funcId, 1, parameter ); break; } parameter->release(); error( 22, {}, zObj ); return 0; } KSGSVariable *KSGSBefehl::prozessMember( KSGSVariable *zVorObj, KSGSBefehlMember *zMem, KSGScriptObj *zObj, KSGSFunktionInstanz *zFI, KSGSKlasseInstanz *zKI ) { if( !zMem ) { error( 22, {}, zObj ); return 0; } switch( zMem->typ ) { case KSGSBefehlMember::BEFEHL: if( !zVorObj && zMem->bef ) return zMem->bef->ausführen( zObj, zFI, zKI ); break; case KSGSBefehlMember::FUNKTION: if( zMem->funk ) return prozessFunktion( zVorObj, zMem->funk, zObj, zFI, zKI ); break; case KSGSBefehlMember::VARIABLE: if( zMem->var ) return prozessVariable( zVorObj, zMem->var, zObj, zFI, zKI ); break; } error( 22, {}, zObj ); return 0; } KSGSVariable *KSGSBefehl::prozessParameter( KSGSBefehlParameter *zParam, KSGScriptObj *zObj, KSGSFunktionInstanz *zFI, KSGSKlasseInstanz *zKI ) { if( !zParam ) { error( 22, {}, zObj ); return 0; } switch( zParam->typ ) { case KSGSBefehlParameter::WERT: if( zParam->wert.getLength() ) { if( !zParam->wert.positionVon( "0x" ) ) return new KSGSIntKlasse( zObj, zParam->wert ); if( zParam->wert.istGleich( "true" ) ) return new KSGSBoolKlasse( zObj, 1 ); if( zParam->wert.istGleich( "false" ) ) return new KSGSBoolKlasse( zObj, 0 ); int anz = zParam->wert.getLength(); bool p = 0; bool num = 1; bool m = 0; for( int i = 0; i < anz; i++ ) { num &= ( zParam->wert[ i ] >= '0' && zParam->wert[ i ] <= '9' ) || zParam->wert[ i ] == '.' || zParam->wert[ i ] == '-'; if( zParam->wert[ i ] == '.' ) { if( p ) num = 0; p = 1; } if( zParam->wert[ i ] == '-' ) { if( m ) num = 0; m = 1; } } if( num ) { if( p ) return new KSGSDoubleKlasse( zObj, zParam->wert ); else return new KSGSIntKlasse( zObj, zParam->wert ); } if( !zParam->wert.positionVon( '"' ) && zParam->wert.positionVon( '"', zParam->wert.anzahlVon( '"' ) - 1 ) == anz - 1 ) { Text *txt = zParam->wert.getTeilText( 1, anz - 1 ); KSGSVariable *ret = new KSGSTextKlasse( zObj, *txt ); txt->release(); return ret; } if( anz == 3 && zParam->wert[ 0 ] == '\'' && zParam->wert[ 2 ] == '\'' ) return new KSGSIntKlasse( zObj, zParam->wert[ 1 ] ); } break; case KSGSBefehlParameter::OBJEKT: if( zParam->objekt.getEintragAnzahl() ) { KSGSVariable *v = 0; int anz = zParam->objekt.getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { KSGSVariable *tmp = prozessMember( v, zParam->objekt.get( i ), zObj, zFI, zKI ); if( v ) v->release(); v = tmp; } return v; } break; } error( 22, {}, zObj ); return 0; } KSGSVariable *KSGSBefehl::prozessErstell( KSGSBefehlErstell *zErst, KSGScriptObj *zObj, KSGSFunktionInstanz *zFI, KSGSKlasseInstanz *zKI ) { if( !zErst ) { error( 22, {}, zObj ); return 0; } KSGSVariable *ret = 0; if( zErst->param ) ret = prozessParameter( zErst->param, zObj, zFI, zKI ); if( !ret ) { KSGSVariableDef def = { zErst->typId, zErst->id, 3, "" }; ret = KSGSVariable::erstellVariable( zObj, &def ); } if( !ret ) { error( 22, {}, zObj ); return 0; } if( ret->getTyp() != zErst->typId ) { KSGSVariable *tmp = ret->umwandelnIn( zErst->typId ); ret->release(); ret = tmp; } zFI->setVariable( zErst->id, ret->getThis() ); return ret; } // Inhalt der KSGSCallBefehl Klasse aus KSGSBefehl.h // Konstruktor KSGSCallBefehl::KSGSCallBefehl( KSGScriptObj *zObj, KSGSLeseBefehl *bef, KSGSCompKlassTable *zKT, KSGSCompFuncTable *zFT, KSGSCompVarTable *zVT, const char *klassName, const char *funktionName ) : KSGSBefehl( Typ::CALL ) { removeKlammer( &bef->befehl ); int abschnittAnz = bef->befehl.anzahlVon( '.' ) + 1; int *abschnittEnde = new int[ abschnittAnz ]; for( int i = 0; i < abschnittAnz - 1; i++ ) abschnittEnde[ i ] = bef->befehl.positionVon( '.', i ); abschnittEnde[ abschnittAnz - 1 ] = bef->befehl.getLength(); int vTyp = -1; for( int i = 0; i < abschnittAnz; i++ ) { int beg = 0; if( i > 0 ) beg = abschnittEnde[ i - 1 ] + 1; int end = abschnittEnde[ i ]; Text *abschnitt = bef->befehl.getTeilText( beg, end ); bool b = 0; KSGSBefehlMember *mem = new KSGSBefehlMember( zObj, abschnitt->getThis(), &bef->debug, zKT, zFT, zVT, klassName, funktionName, &vTyp, &b ); if( !b ) { error( 13, { bef->debug.datei, Text() += bef->debug.zeile, *abschnitt }, zObj ); abschnitt->release(); delete mem; delete[] abschnittEnde; fehler = 1; return; } abschnitt->release(); objekt.add( mem ); } delete[] abschnittEnde; returnTyp = vTyp; } // Destruktor KSGSCallBefehl::~KSGSCallBefehl() { int anz = objekt.getEintragAnzahl(); for( int i = 0; i < anz; i++ ) delete objekt.get( i ); } // constant KSGSVariable *KSGSCallBefehl::ausführen( KSGScriptObj *zObj, KSGSFunktionInstanz *zFI, KSGSKlasseInstanz *zKI ) const { KSGSVariable *v = 0; int anz = objekt.getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { KSGSVariable *tmp = prozessMember( v, objekt.get( i ), zObj, zFI, zKI ); if( v ) v = v->release(); v = tmp; } return v; } // Reference Counting KSGSBefehl *KSGSCallBefehl::release() { ref--; if( !ref ) delete this; return 0; } // Inhalt der KSGSOperatorBefehl Klasse aus KSGSBefehl.h // Konstruktor KSGSOperatorBefehl::KSGSOperatorBefehl( KSGScriptObj *zObj, KSGSLeseBefehl *bef, KSGSCompKlassTable *zKT, KSGSCompFuncTable *zFT, KSGSCompVarTable *zVT, const char *klassName, const char *funktionName ) : KSGSBefehl( Typ::OPERATOR ) { paramL = 0; paramR = 0; removeKlammer( &bef->befehl ); operatorId = hatOperator( &bef->befehl ); if( operatorId < 0 ) { error( 13, { bef->debug.datei, Text() += bef->debug.zeile, bef->befehl }, zObj ); fehler = 1; return; } int opLän = 0; int opPos = getOperatorPos( &bef->befehl, &opLän ); Text *links = bef->befehl.getTeilText( 0, opPos ); bool b = 0; paramL = new KSGSBefehlParameter( zObj, links, &bef->debug, zKT, zFT, zVT, klassName, funktionName, &returnTyp, &b ); if( !b ) { error( 13, { bef->debug.datei, Text() += bef->debug.zeile, bef->befehl }, zObj ); fehler = 1; return; } Text *rechts = bef->befehl.getTeilText( opPos + opLän ); b = 0; int rTyp = -1; paramR = new KSGSBefehlParameter( zObj, rechts, &bef->debug, zKT, zFT, zVT, klassName, funktionName, &rTyp, &b ); if( !b ) { error( 13, { bef->debug.datei, Text() += bef->debug.zeile, bef->befehl }, zObj ); fehler = 1; return; } if( operatorId >= 7 && operatorId <= 14 ) returnTyp = zKT->get( "bool" )->id; } // Destruktor KSGSOperatorBefehl::~KSGSOperatorBefehl() { delete paramL; delete paramR; } // constant KSGSVariable *KSGSOperatorBefehl::ausführen( KSGScriptObj *zObj, KSGSFunktionInstanz *zFI, KSGSKlasseInstanz *zKI ) const { KSGSVariable *l = prozessParameter( paramL, zObj, zFI, zKI ); if( operatorId == KSGS_O_SET && ( l ? l->getTyp() > KSGS_TYP_MAX : 1 ) ) { if( l ) l->release(); if( !paramL || !paramR ) { error( 22, {}, zObj ); return 0; } KSGSVariable *lVObj = 0; int vId = 0; int vS = 0; switch( paramL->typ ) { case KSGSBefehlParameter::WERT: error( 22, {}, zObj ); return 0; case KSGSBefehlParameter::OBJEKT: if( paramL->objekt.getEintragAnzahl() ) { KSGSVariable *v = 0; int anz = paramL->objekt.getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { if( lVObj ) lVObj->release(); lVObj = v ? v->getThis() : 0; KSGSVariable *tmp = 0; switch( paramL->objekt.get( i )->typ ) { case KSGSBefehlMember::BEFEHL: if( i == anz - 1 ) { error( 22, {}, zObj ); if( v ) v->release(); if( lVObj ) lVObj->release(); return 0; } if( !v && paramL->objekt.get( i )->bef ) tmp = paramL->objekt.get( i )->bef->ausführen( zObj, zFI, zKI ); break; case KSGSBefehlMember::FUNKTION: if( i == anz - 1 ) { error( 22, {}, zObj ); if( v ) v->release(); if( lVObj ) lVObj->release(); return 0; } if( paramL->objekt.get( i )->funk ) tmp = prozessFunktion( v, paramL->objekt.get( i )->funk, zObj, zFI, zKI ); break; case KSGSBefehlMember::VARIABLE: vId = paramL->objekt.get( i )->var->varId; vS = paramL->objekt.get( i )->var->varSichtbar; if( paramL->objekt.get( i )->var ) tmp = prozessVariable( v, paramL->objekt.get( i )->var, zObj, zFI, zKI ); break; } if( v ) v->release(); v = tmp; } if( v ) v->release(); } break; default: error( 22, {}, zObj ); return 0; } KSGSVariable *r = paramR ? prozessParameter( paramR, zObj, zFI, zKI ) : 0; if( !r ) { if( lVObj ) lVObj->release(); error( 22, {}, zObj ); return 0; } if( vS == 3 ) // Funktionsvariable { if( lVObj ) lVObj->release(); zFI->setVariable( vId, r->getThis() ); return r; } else if( !vS ) // Scriptvariable { if( lVObj ) lVObj->release(); zObj->setVariable( vId, r->getThis() ); return r; } else // Klassenvariable { if( !lVObj ) { zKI->setVariable( vId, r->getThis() ); return r; } lVObj->setVariable( vId, r->getThis() ); if( lVObj ) lVObj->release(); return r; } } if( !l ) return 0; KSGSVariable *r = paramR ? prozessParameter( paramR, zObj, zFI, zKI ) : 0; KSGSVariable *ret = l->doOperator( operatorId, r ); if( l ) l->release(); return ret; } // Reference Counting KSGSBefehl *KSGSOperatorBefehl::release() { ref--; if( !ref ) delete this; return 0; } // Inhalt der KSGSIfBefehl Klasse aus KSGSBefehl.h // Konstruktor KSGSIfBefehl::KSGSIfBefehl( KSGScriptObj *zObj, KSGSLeseBefehl *bef, KSGSCompKlassTable *zKT, KSGSCompFuncTable *zFT, KSGSCompVarTable *zVT, const char *klassName, const char *funktionName ) : KSGSBefehl( Typ::IF ) { bedingung = 0; int bTyp = -1; bool b = 0; bedingung = new KSGSBefehlParameter( zObj, bef->befehl.getThis(), &bef->debug, zKT, zFT, zVT, klassName, funktionName, &bTyp, &b ); int anz = bef->listA.getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { KSGSLeseBefehl *b = bef->listA.get( i ); KSGSBefehl *ret = 0; switch( b->typ ) { case 0: // call oder operator if( 1 ) { removeKlammer( &b->befehl ); b->befehl.setSuchGrenzen( '(', ')' ); if( hatOperator( &b->befehl ) >= 0 ) ret = new KSGSOperatorBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); else ret = new KSGSCallBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); } break; case 3: // var ret = new KSGSVariableBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 6: // if ret = new KSGSIfBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 7: // for ret = new KSGSForBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 8: // while ret = new KSGSWhileBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 9: // return ret = new KSGSReturnBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 10: // break ret = new KSGSBreakBefehl( b, zKT, zFT, zVT, klassName, funktionName ); break; case 11: // continue ret = new KSGSContinueBefehl( b, zKT, zFT, zVT, klassName, funktionName ); break; } if( !ret ) error( 13, { b->debug.datei, Text() += b->debug.zeile, b->befehl }, zObj ); if( ret && ret->hatFehler() ) ret = ret->release(); if( !ret ) { fehler = 1; return; } bTrue.add( ret ); } anz = bef->listB.getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { KSGSLeseBefehl *b = bef->listB.get( i ); KSGSBefehl *ret = 0; switch( b->typ ) { case 0: // call oder operator if( 1 ) { removeKlammer( &b->befehl ); b->befehl.setSuchGrenzen( '(', ')' ); if( hatOperator( &b->befehl ) >= 0 ) ret = new KSGSOperatorBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); else ret = new KSGSCallBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); } break; case 3: // var ret = new KSGSVariableBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 6: // if ret = new KSGSIfBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 7: // for ret = new KSGSForBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 8: // while ret = new KSGSWhileBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 9: // return ret = new KSGSReturnBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 10: // break ret = new KSGSBreakBefehl( b, zKT, zFT, zVT, klassName, funktionName ); break; case 11: // continue ret = new KSGSContinueBefehl( b, zKT, zFT, zVT, klassName, funktionName ); break; } if( !ret ) error( 13, { b->debug.datei, Text() += b->debug.zeile, b->befehl }, zObj ); if( ret && ret->hatFehler() ) ret = ret->release(); if( !ret ) { fehler = 1; return; } bFalse.add( ret ); } } // Destruktor KSGSIfBefehl::~KSGSIfBefehl() { delete bedingung; } // constant KSGSVariable *KSGSIfBefehl::ausführen( KSGScriptObj *zObj, KSGSFunktionInstanz *zFI, KSGSKlasseInstanz *zKI ) const { KSGSVariable *b = prozessParameter( bedingung, zObj, zFI, zKI ); if( !b ) return 0; if( b->getBool() ) { int anz = bTrue.getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { while( zFI->getStatus() == 1 ) // pause Sleep( 100 ); if( !zFI->getStatus() ) // return break; KSGSVariable *v = bTrue.z( i )->ausführen( zObj, zFI, zKI ); if( v ) v->release(); } } else { int anz = bFalse.getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { while( zFI->getStatus() == 1 ) // pause Sleep( 100 ); if( !zFI->getStatus() ) // return break; KSGSVariable *v = bFalse.z( i )->ausführen( zObj, zFI, zKI ); if( v ) v->release(); } } b->release(); return 0; } // Reference Counting KSGSBefehl *KSGSIfBefehl::release() { ref--; if( !ref ) delete this; return 0; } // Inhalt der KSGSForBefehl Klasse aus KSGSBefehl.h // Konstruktor KSGSForBefehl::KSGSForBefehl( KSGScriptObj *zObj, KSGSLeseBefehl *bef, KSGSCompKlassTable *zKT, KSGSCompFuncTable *zFT, KSGSCompVarTable *zVT, const char *klassName, const char *funktionName ) : KSGSBefehl( Typ::FOR ) { links = 0; rechts = 0; bedingung = 0; Text klammer = bef->befehl.getText(); klammer.setSuchGrenzen( '(', ')' ); removeKlammer( &klammer ); if( klammer.anzahlVon( ';' ) != 2 ) { error( 13, { bef->debug.datei, Text() += bef->debug.zeile, klammer }, zObj ); fehler = 1; return; } Text *l = klammer.getTeilText( 0, klammer.positionVon( ';' ) ); l->setSuchGrenzen( '(', ')' ); removeKlammer( l ); KSGSLeseBefehl *b = new KSGSLeseBefehl(); b->debug.datei = bef->debug.datei.getText(); b->debug.zeile = bef->debug.zeile; b->befehl = l->getText(); l->release(); if( !b->befehl.positionVon( "var" ) ) links = new KSGSVariableBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); else if( hatOperator( &b->befehl ) >= 0 ) links = new KSGSOperatorBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); else if( b->befehl.getLength() ) links = new KSGSCallBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); delete b; if( links && links->hatFehler() ) { fehler = 1; return; } Text *bed = klammer.getTeilText( klammer.positionVon( ';' ) + 1, klammer.positionVon( ';', 1 ) ); bed->setSuchGrenzen( '(', ')' ); removeKlammer( bed ); if( bed->getLength() ) { int bTyp = -1; bool b = 0; bedingung = new KSGSBefehlParameter( zObj, bed, &bef->debug, zKT, zFT, zVT, klassName, funktionName, &bTyp, &b ); if( !b ) { error( 13, { bef->debug.datei, Text() += bef->debug.zeile, klammer }, zObj ); fehler = 1; return; } } else bed->release(); Text *r = klammer.getTeilText( klammer.positionVon( ';', 1 ) + 1 ); r->setSuchGrenzen( '(', ')' ); removeKlammer( r ); b = new KSGSLeseBefehl(); b->debug.datei = bef->debug.datei.getText(); b->debug.zeile = bef->debug.zeile; b->befehl = r->getText(); r->release(); if( hatOperator( &b->befehl ) >= 0 ) rechts = new KSGSOperatorBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); else if( b->befehl.getLength() ) rechts = new KSGSCallBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); delete b; if( rechts && rechts->hatFehler() ) { fehler = 1; return; } int anz = bef->listA.getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { KSGSLeseBefehl *b = bef->listA.get( i ); KSGSBefehl *ret = 0; switch( b->typ ) { case 0: // call oder operator if( 1 ) { removeKlammer( &b->befehl ); b->befehl.setSuchGrenzen( '(', ')' ); if( hatOperator( &b->befehl ) >= 0 ) ret = new KSGSOperatorBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); else ret = new KSGSCallBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); } break; case 3: // var ret = new KSGSVariableBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 6: // if ret = new KSGSIfBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 7: // for ret = new KSGSForBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 8: // while ret = new KSGSWhileBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 9: // return ret = new KSGSReturnBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 10: // break ret = new KSGSBreakBefehl( b, zKT, zFT, zVT, klassName, funktionName ); break; case 11: // continue ret = new KSGSContinueBefehl( b, zKT, zFT, zVT, klassName, funktionName ); break; } if( !ret ) error( 13, { b->debug.datei, Text() += b->debug.zeile, b->befehl }, zObj ); if( ret && ret->hatFehler() ) ret = ret->release(); if( !ret ) { fehler = 1; return; } schleife.add( ret ); } } // Destruktor KSGSForBefehl::~KSGSForBefehl() { if( links ) links->release(); if( rechts ) rechts->release(); delete bedingung; } // constant KSGSVariable *KSGSForBefehl::ausführen( KSGScriptObj *zObj, KSGSFunktionInstanz *zFI, KSGSKlasseInstanz *zKI ) const { KSGSVariable *l = links ? links->ausführen( zObj, zFI, zKI ) : 0; if( l ) l->release(); KSGSVariable *b = prozessParameter( bedingung, zObj, zFI, zKI ); if( !b ) return 0; int anz = schleife.getEintragAnzahl(); while( b->getBool() ) { for( int i = 0; i < anz; i++ ) { while( zFI->getStatus() == 1 ) // pause Sleep( 100 ); if( !zFI->getStatus() ) // return break; if( zFI->getStatus() == 2 ) // continue break; KSGSVariable *v = schleife.z( i )->ausführen( zObj, zFI, zKI ); if( v ) v->release(); } if( zFI->getStatus() == 3 ) // break break; while( zFI->getStatus() == 1 ) // pause Sleep( 100 ); if( !zFI->getStatus() ) // return break; if( !anz ) Sleep( 100 ); KSGSVariable *v = rechts ? rechts->ausführen( zObj, zFI, zKI ) : 0; if( v ) v->release(); if( b ) b->release(); b = prozessParameter( bedingung, zObj, zFI, zKI ); if( !b ) return 0; } b->release(); return 0; } // Reference Counting KSGSBefehl *KSGSForBefehl::release() { ref--; if( !ref ) delete this; return 0; } // Inhalt der KSGSWhileBefehl Klasse aus KSGSBefehl.h // Konstruktor KSGSWhileBefehl::KSGSWhileBefehl( KSGScriptObj *zObj, KSGSLeseBefehl *bef, KSGSCompKlassTable *zKT, KSGSCompFuncTable *zFT, KSGSCompVarTable *zVT, const char *klassName, const char *funktionName ) : KSGSBefehl( Typ::WHILE ) { bedingung = 0; int bTyp = -1; bool b = 0; bedingung = new KSGSBefehlParameter( zObj, bef->befehl.getThis(), &bef->debug, zKT, zFT, zVT, klassName, funktionName, &bTyp, &b ); int anz = bef->listA.getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { KSGSLeseBefehl *b = bef->listA.get( i ); KSGSBefehl *ret = 0; switch( b->typ ) { case 0: // call oder operator if( 1 ) { removeKlammer( &b->befehl ); b->befehl.setSuchGrenzen( '(', ')' ); if( hatOperator( &b->befehl ) >= 0 ) ret = new KSGSOperatorBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); else ret = new KSGSCallBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); } break; case 3: // var ret = new KSGSVariableBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 6: // if ret = new KSGSIfBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 7: // for ret = new KSGSForBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 8: // while ret = new KSGSWhileBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 9: // return ret = new KSGSReturnBefehl( zObj, b, zKT, zFT, zVT, klassName, funktionName ); break; case 10: // break ret = new KSGSBreakBefehl( b, zKT, zFT, zVT, klassName, funktionName ); break; case 11: // continue ret = new KSGSContinueBefehl( b, zKT, zFT, zVT, klassName, funktionName ); break; } if( !ret ) error( 13, { b->debug.datei, Text() += b->debug.zeile, b->befehl }, zObj ); if( ret && ret->hatFehler() ) ret = ret->release(); if( !ret ) { fehler = 1; return; } schleife.add( ret ); } } // Destruktor KSGSWhileBefehl::~KSGSWhileBefehl() { delete bedingung; } // constant KSGSVariable *KSGSWhileBefehl::ausführen( KSGScriptObj *zObj, KSGSFunktionInstanz *zFI, KSGSKlasseInstanz *zKI ) const { KSGSVariable *b = prozessParameter( bedingung, zObj, zFI, zKI ); if( !b ) return 0; int anz = schleife.getEintragAnzahl(); while( b->getBool() ) { for( int i = 0; i < anz; i++ ) { while( zFI->getStatus() == 1 ) // pause Sleep( 100 ); if( !zFI->getStatus() ) // return break; if( zFI->getStatus() == 2 ) // continue break; KSGSVariable *v = schleife.z( i )->ausführen( zObj, zFI, zKI ); if( v ) v->release(); } if( zFI->getStatus() == 3 ) // break break; while( zFI->getStatus() == 1 ) // pause Sleep( 100 ); if( !zFI->getStatus() ) // return break; if( !anz ) Sleep( 100 ); if( b ) b->release(); b = prozessParameter( bedingung, zObj, zFI, zKI ); if( !b ) return 0; } b->release(); return 0; } // Reference Counting KSGSBefehl *KSGSWhileBefehl::release() { ref--; if( !ref ) delete this; return 0; } // Inhalt der KSGSReturnBefehl Klasse aus KSGSBefehl.h // Konstruktor KSGSReturnBefehl::KSGSReturnBefehl( KSGScriptObj *zObj, KSGSLeseBefehl *bef, KSGSCompKlassTable *zKT, KSGSCompFuncTable *zFT, KSGSCompVarTable *zVT, const char *klassName, const char *funktionName ) : KSGSBefehl( Typ::RETURN ) { param = 0; if( bef->befehl.positionVon( "return" ) != 0 ) { error( 13, { bef->debug.datei, Text() += bef->debug.zeile, bef->befehl }, zObj ); fehler = 1; return; } bool b = 0; param = new KSGSBefehlParameter( zObj, bef->befehl.getTeilText( 6 ), &bef->debug, zKT, zFT, zVT, klassName, funktionName, &returnTyp, &b ); if( !b ) { delete param; param = 0; } } // Destruktor KSGSReturnBefehl::~KSGSReturnBefehl() { delete param; } // constant KSGSVariable *KSGSReturnBefehl::ausführen( KSGScriptObj *zObj, KSGSFunktionInstanz *zFI, KSGSKlasseInstanz *zKI ) const { KSGSVariable *v = param ? prozessParameter( param, zObj, zFI, zKI ) : 0; if( v ) zFI->setReturnVariable( v ); zFI->setEnde(); return 0; } // Reference Counting KSGSBefehl *KSGSReturnBefehl::release() { ref--; if( !ref ) delete this; return 0; } // Inhalt der KSGSBreakBefehl Klasse aus KSGSBefehl.h // Konstruktor KSGSBreakBefehl::KSGSBreakBefehl( KSGSLeseBefehl *bef, KSGSCompKlassTable *zKT, KSGSCompFuncTable *zFT, KSGSCompVarTable *zVT, const char *klassName, const char *funktionName ) : KSGSBefehl( Typ::BREAK ) { } // Destruktor KSGSBreakBefehl::~KSGSBreakBefehl() { } // constant KSGSVariable *KSGSBreakBefehl::ausführen( KSGScriptObj *zObj, KSGSFunktionInstanz *zFI, KSGSKlasseInstanz *zKI ) const { zFI->setBreak(); return 0; } // Reference Counting KSGSBefehl *KSGSBreakBefehl::release() { ref--; if( !ref ) delete this; return 0; } // Inhalt der KSGSContinueBefehl Klasse aus KSGSBefehl.h // Konstruktor KSGSContinueBefehl::KSGSContinueBefehl( KSGSLeseBefehl *bef, KSGSCompKlassTable *zKT, KSGSCompFuncTable *zFT, KSGSCompVarTable *zVT, const char *klassName, const char *funktionName ) : KSGSBefehl( Typ::CONTINUE ) { } // Destruktor KSGSContinueBefehl::~KSGSContinueBefehl() { } // constant KSGSVariable *KSGSContinueBefehl::ausführen( KSGScriptObj *zObj, KSGSFunktionInstanz *zFI, KSGSKlasseInstanz *zKI ) const { zFI->setContinue(); return 0; } // Reference Counting KSGSBefehl *KSGSContinueBefehl::release() { ref--; if( !ref ) delete this; return 0; } // Inhalt der KSGSVariableBefehl Klasse aus KSGSBefehl.h // Konstruktor KSGSVariableBefehl::KSGSVariableBefehl( KSGScriptObj *zObj, KSGSLeseBefehl *bef, KSGSCompKlassTable *zKT, KSGSCompFuncTable *zFT, KSGSCompVarTable *zVT, const char *klassName, const char *funktionName ) : KSGSBefehl( Typ::VARIABLE ) { erstell = 0; if( bef->befehl.positionVon( "var" ) != 0 ) { error( 13, { bef->debug.datei, Text() += bef->debug.zeile, bef->befehl }, zObj ); fehler = 1; return; } bool b = 0; erstell = new KSGSBefehlErstell( zObj, bef->befehl.getTeilText( 3 ), &bef->debug, zKT, zFT, zVT, klassName, funktionName, &b ); returnTyp = erstell->typId; if( !b ) { error( 13, { bef->debug.datei, Text() += bef->debug.zeile, bef->befehl }, zObj ); fehler = 1; return; } } // Destruktor KSGSVariableBefehl::~KSGSVariableBefehl() { delete erstell; } // constant KSGSVariable *KSGSVariableBefehl::ausführen( KSGScriptObj *zObj, KSGSFunktionInstanz *zFI, KSGSKlasseInstanz *zKI ) const { return prozessErstell( erstell, zObj, zFI, zKI ); } // Reference Counting KSGSBefehl *KSGSVariableBefehl::release() { ref--; if( !ref ) delete this; return 0; }