Essay - Free Blitz2D

Übersicht Sonstiges Smalltalk

Gehe zu Seite Zurück  1, 2, 3, 4  Weiter

Neue Antwort erstellen

Arrangemonk

BeitragDo, Nov 01, 2007 14:14
Antworten mit Zitat
Benutzer-Profile anzeigen
gibts alles schon!
http://de.wikipedia.org/wiki/FreeBASIC
ingeneur
 

E. Urbach

ehemals "Basicprogger"

BeitragDo, Nov 01, 2007 14:50
Antworten mit Zitat
Benutzer-Profile anzeigen
@ArrangeMonk:
Ich bin lieber von GCC und Visual C++ Compiler abhängig als einem mir unbekannten FreeBasic-Compiler.
Außerdem kann ich dort die Syntax nicht verändern und ebenso kann ich nicht von den hochgelobten Optimierungen der C++ Compiler profitieren. Des Weiteren ist meine gesamte Standard-Lib in C++ geschrieben und nein, man kann sie aufgrund Templates und massivem 1-Zeilen-Inlining nicht direkt per DLL einbinden.

@TheShadow:
Der Parser ist im Moment noch die am wenigsten ausgebaute Komponente.
Ich sagte bereits, dass er noch lange nicht fertig ist, aber ich kann an einem Beispiel zeigen, wie er vorgeht:
Code: [AUSKLAPPEN]
Return a*b+7

Der Parser ist im Moment auf BPC (Blitz Max) beschränkt, weshalb ich jetzt nur die Vorgehensweise bei BPC erkläre. BMax ist zeilen-basiert - ob man will oder nicht. Es gibt zwar das .. am Ende einer Zeile, aber dieses kann der vorherigen Zeile direkt übergeben werden, so dass man immer eine Anweisung pro Zeile hat, so ähnlich ist es beim Semikolon in BMax und mein Code Stats Programm nutzt dieselbe Technik.
Nun gibt es in BMax im Gegensatz zu C++ nur 2 Anweisungstypen:
1.) Zuweisung
2.) Befehl
Jetzt muss der Parser noch wissen, wie diese aufgebaut sind:
1.) Zuweisung: Variable/L-Wert + Gleichheitszeichen + Ausdruck/R-Wert
2.) Befehl: Funktion/Keyword + Parameter
Mit diesen 2 Dingen kann man nun die Zeilen sortieren: Zuweisungen und Befehle.
Beispiele für Zuweisungen:
Code: [AUSKLAPPEN]
x = 5
vector.x = 3
obj.life = 100

Beispiele für Befehle:
Code: [AUSKLAPPEN]
Print a
If x=1 Then
 Return True
EndIf

Nun geht man Zeichen für Zeichen durch und prüft mit IsVarChar(char a), ob es sich (immer noch) um ein Zeichen handelt, welches in Variablen vorkommen darf. Es wird btw noch nicht geprüft, ob das erste Zeichen eine Zahl ist, aber das ist im Moment unwichtig. Wenn nun bspw. ein Leerzeichen gefunden wird,
Code: [AUSKLAPPEN]
Return a*b+7

dann vergleicht er den ersten String, also Return, mit allen Keywords in der Datenbank. Wurde eins gefunden, dann steht fest: Es handelt sich um die Return-Anweisung. Wenn eine Funktion gefunden wurde, wird eben ein call-Knoten in den Tree eingefügt. Nachdem im XML-Tree nun ein <return></return> steht, muss man nun weiter rekursiv aufteilen:
Code: [AUSKLAPPEN]
node->AddNode(GetExpr(parameters));

Nun wird erkannt, dass a*b+7 ein Ausdruck ist, der keine weiteren Funktionen enthält. Mathematische Ausdrücke/Terme werden nicht in XML umgewandelt, das wäre zuviel des Guten, deshalb kann der Parser einen einfachen Text-Knoten erstellen:
Code: [AUSKLAPPEN]
return CreateXMLTextNode("a*b+7");

durch das vorherige AddNode wird es zum return-Knoten hinzugefügt:
Code: [AUSKLAPPEN]
<return>
    a * b + 7
</return>

Wären noch einige zusätzliche Funktionen vorhanden, dann würde es bspw. so aussehen:
Code: [AUSKLAPPEN]
<return>
    <call function="Sin">
        <parameter>
            a * b
        </parameter>
    </call>
    + 7
</return>


Falls es noch irgendwen interessiert, ich habe mal die ersten Seiten abgetippt:
Download PDF
The box said, "Requires Windows XP or better", so I installed Ubuntu | Linux is NOT Windows
Flua :: Profiler für BB und BMax :: Partikel-Engine für BMax :: Lyphia-Projekt Quellcode (BMax) :: Automatische Parallelisierung :: Meine Musik

Arrangemonk

BeitragDo, Nov 01, 2007 15:09
Antworten mit Zitat
Benutzer-Profile anzeigen
@Basicprogger
ich mein nicht dich, sondern vertex, dass der das nehmen soll

aber die erschaffung eines neuen basic dialektes mit eigenem compiler und allem drum und dran is meines erachtens doof, da man sich mit headerfiles das ding includebar einfach im vc++ reinladne kann und dann mit nem {} klammer pseudo basic rumschreiben kann
ingeneur
 

Florian

BeitragDo, Nov 01, 2007 15:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo

Nur eine Idee:

Man könnte doch einen Quelltext in XML umwandeln. Das XML-Ausgabe-Format könnte man so gestalten, das es Programmiersprachen unabhängig ist. ...

Hier ist ein Lexer der Basic Quelltext in Token umwandelt.

Code: [AUSKLAPPEN]

%FALSE=0
%TRUE =1
%NUL  =0

%DEBUG = %TRUE

%SYM_NUL          =  0
%SYM_EOL          =  1
%SYM_EOS          =  2
%SYM_LPARA        =  3
%SYM_RPARA        =  4
%SYM_LEPARA       =  5
%SYM_REPARA       =  6
%SYM_KOMMA        =  7
%SYM_NUM          =  8
%SYM_NUM_CONST    =  9
%SYM_META         = 10
%SYM_STRING       = 12
%SYM_STRING_CONST = 13
%SYM_STRING_VAL   = 14

%SYM_EQ           = 15
%SYM_NE           = 16
%SYM_LE           = 17
%SYM_LT           = 18
%SYM_GE           = 19
%SYM_GT           = 20
%SYM_ID           = 21
%SYM_OP_ADD       = 22
%SYM_OP_SUB       = 23
%SYM_OP_MUL       = 24
%SYM_OP_DIV       = 25

FUNCTION COMPILER(FILENAME AS STRING) AS DWORD
 IF LOADFILE(FILENAME) =%FALSE THEN
  FUNCTION=%FALSE
  EXIT FUNCTION
 END IF

 InitParser



 OUTNR=FREEFILE
 OPEN "Test.asm" FOR OUTPUT AS OUTNR
 PRINT#OUTNR,"%include ""win32n.inc"""
 runParser

 CLOSE #OUTNR

 SHELL "nasm.exe "+"Test.asm"+" -fobj"
 SHELL "ALINK.EXE -c -oPE  -subsys gui Test"

END FUNCTION


SUB InitParser
 GetChar
 SkipWhite
END SUB 

SUB runParser
 DIM TXT AS STRING
 DIM X AS INTEGER
 DIM zeile AS STRING

 getsym
 DO UNTIL %SYM_EOS=SYM_TYPE
  SELECT CASE SYM_TYPE
   CASE %SYM_ID
    SELECT CASE SYM_TEXT
     CASE "sub"
      XSUB

     CASE "function"
      XFUNCTION

     CASE "for"
      XFOR

     CASE "if"
      XIF

     CASE "select"
      XSELECT

     CASE "do"
      XDO

     CASE "table"
      XTABLE

     CASE "type"
      XTYPE

     CASE "asm"
      XASM

    END SELECT
   CASE %SYM_STRING_CONST
    STRING_CONST
  END SELECT
  getsym
 LOOP
 CLOSE#1
END SUB                         


SUB SkipWhite
 IF(EOS) THEN
  EXIT SUB
 END IF
 WHILE IsWhite(Look) OR  Look=ASC($VT) OR  Look=ASC($CR) OR Look=ASC($LF)
  GetChar
 WEND
END SUB

SUB MathSkipWhite
 WHILE IsWhite(Look)
  GetChar
 WEND
END SUB


FUNCTION IsAlpha(T AS DWORD) AS DWORD
 IF T>=ASC("a") AND T<=ASC("z") THEN
  FUNCTION =%TRUE
  EXIT FUNCTION

 ELSEIF T>=ASC("A") AND T<=ASC("Z") THEN
  FUNCTION =%TRUE
  EXIT FUNCTION

 ELSE
  FUNCTION =%FALSE
  EXIT FUNCTION

 END IF
END FUNCTION

FUNCTION IsAlpha2(T AS DWORD) AS DWORD
 IF T>=ASC("a") AND T<=ASC("z") THEN
  FUNCTION =%TRUE
  EXIT FUNCTION

 ELSEIF T>=ASC("A") AND T<=ASC("Z") THEN
  FUNCTION =%TRUE
  EXIT FUNCTION

 ELSEIF T=ASC("_") THEN
  FUNCTION =%TRUE
  EXIT FUNCTION

 ELSE
  FUNCTION =%FALSE
  EXIT FUNCTION

 END IF
END FUNCTION

FUNCTION ishex(T AS DWORD) AS DWORD
 IF T>=ASC("0") AND T<=ASC("9") THEN
  FUNCTION =%TRUE
  EXIT FUNCTION

 ELSEIF T>=ASC("a") AND T<=ASC("f") THEN
  FUNCTION =%TRUE
  EXIT FUNCTION

 ELSEIF T>=ASC("A") AND T<=ASC("F") THEN
  FUNCTION =%TRUE
  EXIT FUNCTION
 ELSE
  FUNCTION =%FALSE
  EXIT FUNCTION
 END IF
END FUNCTION

FUNCTION h2d(T AS DWORD) AS DWORD
 IF T>=ASC("0") AND T<=ASC("9") THEN
  FUNCTION=T-ASC("0")
  EXIT FUNCTION
 ELSEIF T>=ASC("a") AND T<=ASC("f") THEN
  FUNCTION= T-ASC("a")+10
  EXIT FUNCTION
 ELSEIF T>=ASC("A") AND T<=ASC("F") THEN
  FUNCTION=T-ASC("A")+10
  EXIT FUNCTION
 ELSE
  ERR_OUT "Bad numeric format, nor hex neither decimal"
 END IF
END FUNCTION

FUNCTION IsAlnum(T AS DWORD) AS DWORD
 IF IsAlpha(T) OR IsDigit(T) THEN
  FUNCTION =%TRUE
  EXIT FUNCTION
 ELSE
  FUNCTION =%FALSE
  EXIT FUNCTION
 END IF
END FUNCTION

FUNCTION IsDigit(T AS DWORD) AS DWORD
 IF T=>ASC("0") AND T=<ASC("9") THEN
  FUNCTION =%TRUE
  EXIT FUNCTION
 ELSE
  FUNCTION =%FALSE
  EXIT FUNCTION
 END IF
END FUNCTION
                                             

SUB GetSym
 SELECT CASE AS LONG LOOK
  CASE ASC("'")

  CASE ASC("+")
   SYM_TYPE=%SYM_OP_ADD
   #IF %DEBUG = %TRUE
    SYM_TEXT = "+"
   #ENDIF
   Match ASC("+")
   EXIT SUB

  CASE ASC("-")
   SYM_TYPE=%SYM_OP_SUB
   #IF %DEBUG = %TRUE
    SYM_TEXT = "-"
   #ENDIF
   Match ASC("-")
   EXIT SUB

  CASE ASC("*")
   SYM_TYPE=%SYM_OP_MUL
   #IF %DEBUG = %TRUE
    SYM_TEXT = "*"
   #ENDIF
   Match ASC("*")
   EXIT SUB

  CASE ASC("@")
   Match ASC("@")

  CASE ASC("/")
   SYM_TYPE=%SYM_OP_DIV
   #IF %DEBUG = %TRUE
    SYM_TEXT = "/"
   #ENDIF
   Match ASC("/")
   EXIT SUB

  CASE ASC("<")
   Match ASC("<")

  CASE ASC(">")
   Match ASC(">")
   SELECT CASE AS LONG LOOK
    CASE ASC("=")
     SYM_TYPE=%SYM_GE
     #IF %DEBUG = %TRUE
      SYM_TEXT = ">="
     #ENDIF
     Match ASC("=")
     EXIT SUB

    CASE ASC("<")
     SYM_TYPE=%SYM_NE
     #IF %DEBUG = %TRUE
      SYM_TEXT = "><"
     #ENDIF
     Match ASC("<")
     EXIT SUB

    CASE ELSE
     SYM_TYPE=%SYM_GE
     #IF %DEBUG = %TRUE
      SYM_TEXT = "="
     #ENDIF
     EXIT SUB
   END SELECT

  CASE ASC("=")
   Match ASC("=")
   SELECT CASE AS LONG LOOK
    CASE ASC("<")
     SYM_TYPE=%SYM_LE
     #IF %DEBUG = %TRUE
      SYM_TEXT = "=<"
     #ENDIF
     Match ASC("<")
     EXIT SUB

    CASE ASC(">")
     SYM_TYPE=%SYM_GE
     #IF %DEBUG = %TRUE
      SYM_TEXT = "=>"
     #ENDIF
     Match ASC(">")
     EXIT SUB

    CASE ELSE
     SYM_TYPE=%SYM_EQ
     #IF %DEBUG = %TRUE
      SYM_TEXT = "="
     #ENDIF
     EXIT SUB
   END SELECT


  CASE ASC("%")
   getchar
   IF (ASC("a")=<LOOK AND ASC("z")=>LOOK) OR (ASC("A")=>LOOK AND ASC("Z")=<LOOK) THEN
    SYM_TEXT=""
    DO
     SYM_TEXT = SYM_TEXT+LCASE$(CHR$(LOOK))
     GetChar
    LOOP WHILE (LOOK>=ASC("a") AND LOOK<=ASC("z")) OR (LOOK>=ASC("A") AND LOOK<=ASC("Z")) OR (LOOK>=ASC("0") AND LOOK<=ASC("9")) OR LOOK>=ASC("_")
    SYM_TYPE=%SYM_META
    MathSkipWhite
    EXIT SUB
   ELSE
   END IF

  CASE ASC("#")
   getchar
   IF (ASC("a")=<LOOK AND ASC("z")=>LOOK) OR (ASC("A")=>LOOK AND ASC("Z")=<LOOK) THEN
    SYM_TEXT=""
    DO
     SYM_TEXT = SYM_TEXT+LCASE$(CHR$(LOOK))
     GetChar
    LOOP WHILE (LOOK>=ASC("a") AND LOOK<=ASC("z")) OR (LOOK>=ASC("A") AND LOOK<=ASC("Z")) OR (LOOK>=ASC("0") AND LOOK<=ASC("9")) OR LOOK>=ASC("_")
    SYM_TYPE=%SYM_META
    MathSkipWhite
    EXIT SUB
   ELSE
    SYM_TEXT="#"
    MathSkipWhite
   END IF

  CASE ASC("$")
   getchar
   IF (ASC("a")=<LOOK AND ASC("z")=>LOOK) OR (ASC("A")=>LOOK AND ASC("Z")=<LOOK) THEN
    SYM_TEXT=""
    DO
     SYM_TEXT = SYM_TEXT+LCASE$(CHR$(LOOK))
     GetChar
    LOOP WHILE (LOOK>=ASC("a") AND LOOK<=ASC("z")) OR (LOOK>=ASC("A") AND LOOK<=ASC("Z")) OR (LOOK>=ASC("0") AND LOOK<=ASC("9")) OR LOOK>=ASC("_")
    SYM_TYPE=%SYM_STRING_CONST
    MathSkipWhite
    EXIT SUB
   ELSE
    SYM_TEXT="$"
    Match ASC("$")
   END IF

  CASE ASC("""")
   SYM_TEXT=""
   GetChar
   DO WHILE (LOOK<>ASC("""") AND ASC($CR)<>LOOK AND ASC($LF)<>LOOK)
    SYM_TEXT = SYM_TEXT+CHR$(LOOK)
    GetChar
   LOOP
   SYM_TYPE=%SYM_STRING_VAL

   IF ASC("""")=LOOK THEN
    Match ASC("""")
    MathSkipWhite
   ELSE
    MathSkipWhite
   END IF

  CASE ASC("(")
   SYM_TYPE=%SYM_LPARA
   #IF %DEBUG = %TRUE
    SYM_TEXT="("
   #ENDIF
   Match ASC("(")
   EXIT SUB

  CASE ASC(")")
   SYM_TYPE=%SYM_RPARA
   #IF %DEBUG = %TRUE
    SYM_TEXT=")"
   #ENDIF
   Match ASC(")")
   EXIT SUB

  CASE ASC(",")
   SYM_TYPE=%SYM_KOMMA
   #IF %DEBUG = %TRUE
    SYM_TEXT=","
   #ENDIF
   Match ASC(",")
   EXIT SUB

  CASE ASC("[")
   #IF %DEBUG = %TRUE
    SYM_TEXT="["
   #ENDIF
   SYM_TYPE=%SYM_LEPARA
   Match ASC("[")
   EXIT SUB

  CASE ASC("]")
   #IF %DEBUG = %TRUE
    SYM_TEXT="]"
   #ENDIF
   SYM_TYPE=%SYM_REPARA
   Match ASC("]")
   EXIT SUB


  CASE ASC("0") TO ASC("9")
   SYM_TEXT=""
   DO
    SYM_TEXT = SYM_TEXT+CHR$(LOOK)
    GetChar
   LOOP WHILE (LOOK>=ASC("0") AND LOOK<=ASC("9"))
   SYM_TYPE=%SYM_NUM
   MathSkipWhite
   EXIT SUB

  CASE ASC("a") TO ASC("z"),ASC("A") TO ASC("Z")
   SYM_TEXT=""
   DO
    SYM_TEXT = SYM_TEXT+LCASE$(CHR$(LOOK))
    GetChar
   LOOP WHILE (LOOK>=ASC("a") AND LOOK<=ASC("z")) OR (LOOK>=ASC("A") AND LOOK<=ASC("Z")) OR (LOOK>=ASC("0") AND LOOK<=ASC("9")) OR LOOK>=ASC("_")
   SYM_TYPE=%SYM_ID
   MathSkipWhite
   EXIT SUB

  CASE ASC($CR),ASC($LF)
   SYM_TYPE=%SYM_EOL
   SYM_TEXT =""
   SkipWhite
   EXIT SUB

  CASE %NUL
   SYM_TYPE=%SYM_EOS
   SYM_TEXT =""


  CASE ELSE
   MSGBOX CHR$(LOOK)
   SYM_TYPE=%SYM_NUL
   SYM_TEXT =""
   EXIT SUB

 END SELECT
END SUB


FUNCTION LOADFILE(FILENAME AS STRING) AS DWORD
 DIM FILENR  AS DWORD
 DIM FILELOF AS DWORD
 DIM PUFFER  AS STRING
 DIM MEM     AS DWORD

 FILENR=FREEFILE
 OPEN FILENAME FOR BINARY AS FILENR
 FILELOF=LOF(FILENR)

 GET$ FILENR,FILELOF,PUFFER
 CLOSE#FILENR

 MEM=GetAsciiz(PUFFER)
 IF MEM = %FALSE THEN
  FUNCTION = %FALSE
  EXIT FUNCTION
 END IF

 INCR CURFILE
 FILE(CURFILE).FILE=GetAsciiz(FILENAME)
 FILE(CURFILE).LINENR = 1
 FILE(CURFILE).MEM    = MEM
 FILE(CURFILE).MEMPTR = MEM

 FUNCTION = %TRUE
END FUNCTION               
 

E. Urbach

ehemals "Basicprogger"

BeitragDo, Nov 01, 2007 15:30
Antworten mit Zitat
Benutzer-Profile anzeigen
@ArrangeMonk:
Sorry, hab ja vorher was gepostet, dachte das wär auf mich bezogen.

Aber habe ich dich richtig verstanden mit dem Pseudo-Basic?
Code: [AUSKLAPPEN]
#define If if(
#define Then ) {
#define Else } else {
#define EndIf }

Das ist aber eine seeehr schlechte Methode, nicht nur weil man #define besser meiden sollte, sondern weil man damit schnell auf Beschränkungen stößt.
Außerdem hast du glaube ich das mit dem "Compiler" missverstanden, es geht nicht um die Übersetzung in Assembler/EXEs, sondern um die Übersetzung in C++ Code und das automatische Linken, so dass sich der User nicht damit auskennen muss. Na ja, wenn du's richtig verstanden hast, entschuldige bitte Wink

Zitat:
Man könnte doch einen Quelltext in XML umwandeln. Das XML-Ausgabe-Format könnte man so gestalten, das es Programmiersprachen unabhängig ist. ...

Ist es zurzeit auch Wink
The box said, "Requires Windows XP or better", so I installed Ubuntu | Linux is NOT Windows
Flua :: Profiler für BB und BMax :: Partikel-Engine für BMax :: Lyphia-Projekt Quellcode (BMax) :: Automatische Parallelisierung :: Meine Musik

TheShadow

Moderator

BeitragDo, Nov 01, 2007 15:43
Antworten mit Zitat
Benutzer-Profile anzeigen
hm... Basicprogger

Du machst es dir ganz schön LEICHT - da du deine Token nicht weiter in Tree aufteilst... Dir ist dann doch schon klar, dass du dann so einen Code nicht einfach wahlweise nach C++ oder JS umwandeln kannst...


damit meine ich sowas wie:

<return>
a * b + 7
</return>

Korrekt müsste man

Code: [AUSKLAPPEN]
RETURN{KEYWORD:RETURN}
     |
    +{SYMBOL:PLUS}
   /              \
  *{SYMBOL:MULT}  7{NUMBER:INT}
 /              \
a{VARIABLE:INT}   b{VARIABLE:FLOAT}


in etwa so aufteilen - das ist jetzt vereinfacht - in wirklichkeit muß noch für a und b eine Tabelle existieren. Sind a und/oder b nicht in Tabelle - dann gibts Error. Die Typen von a und b werden aus Tabelle geholt.


was du dann machst, weiß ich nicht

da ich in C++ und nicht nach XML umwandeln würde, würde ich dann aus so einem Tree wieder einen C++ Code generieren... wobei einzelne Zweige wieder aufgelöst und dabei konvertiert werden müssen:

Man löst das dann in etwa so auf:
a ist INT und b ist FLOAT - Ergebis von * ist dann FLOAT
* ist FLOAT und 7 ist INT - Ergebnis von + ist dann FLOAT
RETURN liefert FLOAT zurück - ist der Rückgabetyp anders wie definiert, dann muss es wieder gewandelt werden - etwa nach INT. Ist Konvertierung nicht möglich, dann kommt Error.


So wie ich sehe prüfst du das Ergebnis NICHT - wird bei RETURN ein Objekttyp oder Pointer erwartet - dann gibt es schon Probleme - meinst du nicht? Da JS z.B. gar keine Pointer hat - muss deine Sprache insgesamt auf Pointer verzichten. Du verstehst dann dass die Sprache limitiert wäre? D.h. du kannst später nicht C++ nach XML wandeln, da du überhaupt keien Pointer nutzen kannst - weswegen du dann auf Basic festsitzen würdest...

Ich habe mir schon große gedanken gemacht und je mehr ich nachdachte, desto mehr habe ich begriffen, dass dieses Thema hochkomplex ist.

Das was oben beschrieben ist - is z.B. nur ein Bruchteil - es wird komplex wenn man noch module, classen, methoden, vererbung, pointer usw. macht...

ein Code wie

!ptr = blub.slup() * 7

muß dann immer noch gut konvertiert werden können

in C würde so ein Code am Ende etwa so aussehen:

*ptr = blub->slup() * 7;

Wobei ! nicht einfach durck * und . nicht einfach durch -> ersetzt werden, sondern aus dem TREE nach bestimmten Regeln konvertiert werden müssen. FÜr jede Art der Konvertierung aus dem Tree muß eine bestimmte Regel existieren. Genau wie für Typumwandlungen. Denn einige Typen können konvertiert werden BYTE->INT - andere dagegen müssen entw. explizit umgewandelt werden INT->BYTE - andernfalls gib es error.


Ich persönlich wollte gerne einen "Compiler" coden, der alle Fehler abfangen würde - einzig Linkfehler von ld.exe (mingw) kann es dann nicht mehr abfangen...
 

E. Urbach

ehemals "Basicprogger"

BeitragDo, Nov 01, 2007 16:11
Antworten mit Zitat
Benutzer-Profile anzeigen
@TheShadow: Lass mich raten, du hast dir nicht den Speichermanagement-Teil in der PDF-Datei durchgelesen?

Ich versuch es nochmal konkreter zu beschreiben, meine vorherige Beschreibung war ja etwas abstrakt:
Fangen wir ganz bei 0 an.
Es gibt Types.
Und es gibt Structs.
Types sind Structs, aber sie werden dynamisch initialisiert.
In BPC gibt es nur Types, sonst wäre es - wie du schon gesagt hast - nicht möglich, solche Dinge zu portieren.
Es werden somit alle Variablen, die der User definiert, dynamisch angelegt.
Jetzt zum GC von Java und der Sache mit JavaScript:
Zitat:
Da JS z.B. gar keine Pointer hat - muss deine Sprache insgesamt auf Pointer verzichten.

Sie verzichtet auf C-Pointer - aber nicht auf SharedPtr.
Ich versuch es mal in Code auszudrücken:
Code: [AUSKLAPPEN]
Local window:Window = New Window("Hello", -1, -1, 640, 480)
Local button:Button = New Button("Test")
window.Add(button)
button.SetPosition(5, 5)
button.SetSize(96, 24)
button.OnClick(ShowMsg, "Hello World")

Nun sieht der Code in C++ so aus:
Code: [AUSKLAPPEN]
Window window = new Window("Hello", -1, -1, 640, 480);
Button button = new Button("Test");
window->Add(button);
button->SetPosition(5, 5);
button->SetSize(96, 24);
button->OnClick(ShowMsg, "Hello World");

window und button sind hier SharedPtr, keine Stack-Objekte.
In Java sieht er fast genauso aus und bei JS ist es auch nur eine Frage der Syntax.
Man kann es sogar sehr gut mit Java vergleichen: Ints, Floats, etc. werden per call by value übergeben, die Type-Instanzen per call by reference.

Zitat:
Man löst das dann in etwa so auf:
a ist INT und b ist FLOAT - Ergebis von * ist dann FLOAT
* ist FLOAT und 7 ist INT - Ergebnis von + ist dann FLOAT
RETURN liefert FLOAT zurück - ist der Rückgabetyp anders wie definiert, dann muss es wieder gewandelt werden - etwa nach INT. Ist Konvertierung nicht möglich, dann kommt Error.

Ich hätt's nicht besser beschreiben können Wink

Zitat:
Ich habe mir schon große gedanken gemacht und je mehr ich nachdachte, desto mehr habe ich begriffen, dass dieses Thema hochkomplex ist.

Ist dir aber früh aufgefallen Smile

Zitat:
Du machst es dir ganz schön LEICHT - da du deine Token nicht weiter in Tree aufteilst...

Ja, ich weiß, erinnerst du dich noch an die Frage in meinem "Konzept-Thread"? Ich war mir nicht sicher, dann ist mir aber aufgefallen, dass man bei solchen Ausdrücken eigentlich nur ein simples String-Replace machen muss, um sie in andere Sprachen umzuwandeln. Ich beschäftige mich gerade mit den anderen Teilen des Parsers, um genau zu sein mit den Befehlen und der Operatoren-Priorität.
Möglicherweise werde ich heute noch eine feinere Strukturierung mit typensicheren Ausdrücken implementieren.
Ich habe dir ja gesagt, dass der Parser noch nicht fertig ist, lass mir noch ein wenig Zeit, dann kannst du mich zu Tode kritisieren Wink
The box said, "Requires Windows XP or better", so I installed Ubuntu | Linux is NOT Windows
Flua :: Profiler für BB und BMax :: Partikel-Engine für BMax :: Lyphia-Projekt Quellcode (BMax) :: Automatische Parallelisierung :: Meine Musik

TheShadow

Moderator

BeitragDo, Nov 01, 2007 16:24
Antworten mit Zitat
Benutzer-Profile anzeigen
aber ich verstehe nicht dein oberer Code (basic-like) sieht genau aus wie c++
da werden echt nur paar paar wörter getauscht... hm...

Zitat:
Ich war mir nicht sicher, dann ist mir aber aufgefallen, dass man bei solchen Ausdrücken eigentlich nur ein simples String-Replace machen muss, um sie in andere Sprachen umzuwandeln.


Das ist dir dirty-methode - wenn es geht, dann ok - die types MÜSSEN jedoch geprüft werden - andernfalls überlässt du es dem c++ compiler - der dann fehler ausspucken wird. Du wärst dann auch nicht in der Lage sein notwenige Konvertierungen durchzuführen...

wie gesagt normal müssen die Tokens bis ins letzte Detail in tree abgebildet werden...
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2

Vertex

BeitragFr, Nov 02, 2007 0:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
@Basicprogger
ich mein nicht dich, sondern vertex, dass der das nehmen soll

aber die erschaffung eines neuen basic dialektes mit eigenem compiler und allem drum und dran is meines erachtens doof, da man sich mit headerfiles das ding includebar einfach im vc++ reinladne kann und dann mit nem {} klammer pseudo basic rumschreiben kann

a) geht es hier darum, einen open source Compiler für Blitz2d und nicht für QBASIC zu schaffen und b) ist diese Test-Sprache nur dazu da, um zu sehen, wie kompliziert so etwas ist.

Wie gesagt, ich habe eine kleine Test-Grammatik entwickelt, um zu sehen, ob das Projekt überhaupt ohne weiteres möglich ist. Erste Ergebnisse: MiniBasic (den Namen wird es sicher schon ein paar hundert mal geben, aber das ist ja wie gesagt nur ein Test)

Beispiel
Code: [AUSKLAPPEN]
Const NUMBER : Int = 10
Var I : Int

For I = 1 To NUMBER
   Print("Hallo Welt " + I)
Next


Der Scanner scheint einwandfrei zu funktionieren und der Parser meldet mir schon Syntaxfehler. Vorbereitungen für den AST sind getroffen. Ich muss nur die Rückgabe-Werte der ParseXYZ Methoden von True/False auf Null/Instanz umstellen.

Bspw.:
Code: [AUSKLAPPEN]
   Method ParseWhileLoop:TWhileLoop(Match:Int)
      Rem
         WhileLoop = 'While' Expression
                     {Statement}
                     'Wend';
      End Rem

      Local WhileLoop : TWhileLoop

      Self.PushToken()

      ' 'While'
      If Not Self.MatchId(TOKEN_KW_WHILE, Match) Then
         Self.PopToken()
         Return Null
      EndIf
      Self.NextToken()

      WhileLoop = New TWhileLoop

      ' Expression
      WhileLoop.Condition = Self.ParseExpression(True)
      If Not WhileLoop.Condition Then
         Self.PopToken()
         Return Null
      EndIf

      ' {Statement}
      While WhileLoop.AddBody(Self.ParseStatement(False))
      Wend

      ' 'Wend'
      If Not Self.MatchId(TOKEN_KW_WEND, True) Then
         Self.PopToken()
         Return Null
      EndIf
      Self.NextToken()

      Self.PopToken(True)
      Return WhileLoop
   End Method


Basicprogger: Viel wichtiger wäre eine Beschreibung deiner XML "Sprache". Also welche Tags es gibt bzw. wenn es OpenSource ist, wo man den Source findet.

mfg olli
vertex.dreamfall.at | GitHub

TheShadow

Moderator

BeitragFr, Nov 02, 2007 10:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Ha Vertex - ich dachte du hast die Sprachregeln aufgestellt und einen Parser geschrieben der nach den Regeln arbeitet - du hast es aber doch nativ eingecodet... Smile ist wohl auch besser so


So wie ich verstehe, dann fügst du alle token innerhalb von while zu einem while-object - und arbeitest den rest ebenfalls rekursiv ab... das ist auch eine interessante Lösung - die aber schon viel Speicher brauchen wird... hast du noch sowas wie ENDOFLINE-Token?

ich hätte das z.B. anders gemacht... ich hätte alles zeilenweise gescant... ich weiß nicht ob es nun besser wäre...

z.B. kommt LOOP - dann wird zu einer tabelle Loop-Signatur angefügt. Kommt dann FOR, dann wird For-Signatur zu Tabelle hinzugefügt. Kommt END, dann wird ein Eintrag aus Tabelle gelöscht usw...
Ist etwas nicht möglich - z.B. FOR innerhalb von CLASS, dann kommt error.

Dadurch wäre der Scanner "flach" - während dein jetziger scanner die Token mehrmals in "BLÖCKE" umpackt und so nur zeit verliert

Man denke an CLASS>METHODE>WHILE>FOR>IF
Für die CLASS müsstest du dann ersmal das ende von class suchen - und das liegt irgendwo 4x weiter - dann musst du für METHODE das Ende suchen usw... zuvor müsstest du noch den gesamten Code in Token aufteilen und im Speicher halten...

Hm...
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2
 

E. Urbach

ehemals "Basicprogger"

BeitragFr, Nov 02, 2007 14:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Basicprogger: Viel wichtiger wäre eine Beschreibung deiner XML "Sprache". Also welche Tags es gibt bzw. wenn es OpenSource ist, wo man den Source findet.

Projektseite
Code
Alle "Branches"
Bug Reports
Feature Requests
Fragen
Überarbeitete Dokumentation
Kompilierte 64-Bit-Binary für Linux
Alte Projektseite

Wenn es dir nicht reicht, sag bescheid, dann kann ich weitere Informationen hinzufügen.

@TheShadow: Ich habe die XML-Zwischenstufe entfernt Smile Nicht komplett, aber zumindest das Speichern in eine XML-Datei und das erneute Parsen. Erschien mir ein wenig sinnlos, die Datei zu speichern und erneut zu parsen, wo ich doch die XML-Struktur schon im Speicher habe. Somit kann man eine XML-Datei erstellen lassen, aber normalerweise wird sie intern im Speicher aufbewahrt als abstrakter Baum.
In irgendeinem Format muss ich die Daten sowieso im Speicher halten, sonst kann ich keine Fehler abfangen. XML ist dazu bestens geeignet und hat einen sehr geringen Overhead.

Das Interface habe ich jetzt ebenfalls verbessert. Es ist jetzt noch abstrakter als vorhin und prüft bereits, ob bestimmte Keywords in Klassen, Funktionen, etc. enthalten sein dürfen. Trotzdem bin ich noch weit vom Ziel entfernt - nämlich 95 % aller Fehler abzufangen (Linker-Fehler natürlich nicht, wie auch?).

Das Parsen von mathematischen Ausdrücken werde ich ebenfalls implementieren, ich habe schon einen guten Ansatz, der nicht viel Zeit benötigt, er basiert auf der Operatorenpriorität, aber auf Details möchte ich hier nicht eingehen.

Aktuelle Version ist zurzeit 0.1.4. Bei 0.5 werde ich die Beta auch für Windows kompilieren, dann kann sie jeder ausgiebig testen.
The box said, "Requires Windows XP or better", so I installed Ubuntu | Linux is NOT Windows
Flua :: Profiler für BB und BMax :: Partikel-Engine für BMax :: Lyphia-Projekt Quellcode (BMax) :: Automatische Parallelisierung :: Meine Musik
  • Zuletzt bearbeitet von E. Urbach am Sa, Nov 03, 2007 14:21, insgesamt einmal bearbeitet

Vertex

BeitragFr, Nov 02, 2007 21:25
Antworten mit Zitat
Benutzer-Profile anzeigen
TheShadow, jup aber ich habe da ein interessantes Tool gefunden:
Jaccie - ein Compiler-Compiler
Also das Parser-Tool habe ich noch nicht zum laufen gebracht, aber selbst der Scanner ist nützlich. Der erzeugte Compiler ist allerdings Java-Code.

minibasic.zip
Aus dem Beispiel
Code: [AUSKLAPPEN]
Const NUMBER : Int = 10
Var I : Int

For I = 1 To NUMBER
   Print("Hallo Welt " + I)
Next


Wird nun folgender AST generiert:
Code: [AUSKLAPPEN]
<?xml version="1.0"?>
<ast>
 <program>
  <constantDecleration>
   <constant>
    <decleration name="NUMBER" valueType="Integer" />
    <expression>
     <simpleExpression>
      <term>
       <factor>
        <integer>10</integer>
       </factor>
      </term>
     </simpleExpression>
    </expression>
   </constant>
  </constantDecleration>
  <variableDecleration>
   <variable>
    <decleration name="I" valueType="Integer" />
   </variable>
  </variableDecleration>
  <forLoop>
   <assignment>
    <identifier>I</identifier>
    <expression>
     <simpleExpression>
      <term>
       <factor>
        <integer>1</integer>
       </factor>
      </term>
     </simpleExpression>
    </expression>
   </assignment>
   <to>
    <expression>
     <simpleExpression>
      <term>
       <factor>
        <identifier>NUMBER</identifier>
       </factor>
      </term>
     </simpleExpression>
    </expression>
   </to>
   <functionCall>
    <identifier>Print</identifier>
    <expression>
     <simpleExpression>
      <term>
       <factor>
        <string>Hallo Welt </string>
       </factor>
      </term>
      <plus />
      <simpleExpression>
       <term>
        <factor>
         <identifier>I</identifier>
        </factor>
       </term>
      </simpleExpression>
     </simpleExpression>
    </expression>
   </functionCall>
  </forLoop>
 </program>
</ast>


Man möge mir mal hier die grauenhafte Programmierung verzeihen. Das XML Modul habe ich jetzt nur auf die Schnelle hinein gequetscht, um überhaupt ein Ergebnis zu sehen.

Basicprogger, sorry, kam jetzt den ganzen Tag nicht an den Code von dir ran. Gerade wo ich hier schreibe geht es nun auf einmal. Werde mich also später nochmal dazu äußern.

mfg olli

Edit:
Ich hoffe, das ist die korrekte EBNF von BlitzBasic. Hat mich jetzt viel Nerven gekostet Smile
Code: [AUSKLAPPEN]
(* Parser *)
Program             = {ConstantDeclaration
                    | Statement};

IncludeDirective    = 'Include' StringLiteral;

ConstantDeclaration = 'Const'  Constant {',' Constant};
Constant            = Identifier ['%' | '#' | '$'] '=' Expression;

ArrayDeclaration    = 'Dim' Identifier ['%' | '#' | '$' | '.' Identifier]
                      '(' Expression {',' Expression} ')';

LocalDeclaration    = 'Local' Variable {',' Variable};
GlobalDeclaration   = 'Global' Variable {',' Variable};
Variable            = Identifier ['%' | '#' | '$' | '.' Identifier] ['=' Expression];

DataDefinition      = 'Data' Expression {',' Expression};
RestoreStatement    = 'Restore' [Identifier];
ReadStatement       = 'Read' Name {',' Name};

GotoStatement       = 'Goto' Identifier;
GosubStatement      = 'Gosub' Identifier;

IfStatement         = ('If' Expression ['Then'] Statement)
                    | ('If' Expression ['Then']
                      {Statement}
                      {('ElseIf' | 'Else If') Expression ['Then'] {Statement}}
                      ['Else' {Statement}]
                      ('EndIf' | 'End If'));

SelectStatement     = 'Select' Expression
                      {'Case' Expression {Statement}}
                      ['Default' {Statement}]
                      'End Select';

ExitStatement       = 'Exit';
ReturnStatement     = 'Return';

RepeatStatement     = 'Repeat'
                      {Statement}
                      ('Until' Expression | 'Forever');

WhileStatement      = 'While' Expression
                      {Statement}
                      'Wend';

ForStatement        = 'For' Assignment 'To' Expression ['Step' Expression]
                      {Statement}
                      'Next';

EachStatement       = 'For' Name '=' 'Each' Identifier
                      {Statement}
                      'Next';

AssignStatement     = Name '=' (
                    | 'New' Identifier
                    | BeforeExpression
                    | AfterExpression
                    | Expression);

Name                = Identifier ['.' Identifier]
                      ['(' [Expression {',' Expression}] ')']
                      [{'\' Identifier}+ ['%' | '#' | '$']]
                    | Identifier ['%' | '#' | '$' | '.' Identifier];

CallStatement       = Identifier ('(' [Expression {',' Expression}] ')')
                    | Identifier [Expression {',' Expression}];

InsertStatement     = 'Insert' Name (BeforeExpression | AfterExpression);
DeleteStatement     = 'Delete' ('(' Name ')' | Name));
BeforeExpression    = 'Before' ('(' Name ')' | Name));
AfterExpression     = 'After' ('(' Name ')' | Name));

InsertStatement     = 'Insert' Name ('Before' | 'After');

Statement           = IncludeDirective
                    | ArrayDeclaration
                    | LocalDeclaration
                    | GlobalDeclaration
                    | RestoreStatement
                    | ReadStatement
                    | GotoStatement
                    | GosubStatement
                    | ExitStatement
                    | ReturnStatement
                    | IfStatement
                    | SelectStatement
                    | RepeatStatement
                    | WhileStatement
                    | ForStatement
                    | EachStatement
                    | AssignStatement
                    | CallStatement

Function            = 'Function' Identifier ['%' | '#' | '$' | '.' Identifier]
                      '(' [Variable {',' Variable}] ')'
                      {('Return' ('(' Expression ')' | Expression)) | Statement}
                      'End Function';


TypeDeclaration     = 'Type' Identifier
                      {'Field' Identifier ['%' | '#' | '$' | '.' Identifier]}
                      'End Type';

Expression          = ['Not'] BitExpression {'Not' BitExpression};
BitExpression       = Relation {('And' | 'Or' | 'Xor') Relation};
Relation            = AddExpression {RelationOperator AddExpression};
RelationOperator    = '=' | '<>' | '><' | '<' | '<=' | '=<' | '>' | '>=' | '=>';
AddExpression       = Shift {('+' | '-') Shift};
Shift               = Term {('Shl' | 'Shr' |'Sar') Term};
Term                = Power {('*' | '/' | 'Mod') Power};
Power               = Unary {'^' Unary};
Unary               = ['~'] Factor {'~' Factor};
Factor              = IntegerLiteral
                    | FloatLiteral
                    | StringLiteral
                    | '(' Expression ')'
                    | TypeCast
                    | Name;
TypeCast            = 'Int' '(' Expression ')'
                    | 'Float' '(' Expression ')'
                    | 'Str' '(' Expression ')';

(* Lexer *)

Comment        = ';' {CHARACTERS-?EOL?};

Digit          = '0' | '1' | '2' | ... | '9';
BinaryDigit    = '0' | '1';
HexDigit       = Digit
               | 'A' | 'B' | 'C' | ... | 'F'
               | 'a' | 'b' | 'c' | ... | 'f';
Letter         = 'A' | 'B' | 'C' | ... | 'Z'
               | 'a' | 'b' | 'c' | ... | 'z';

FloatLiteral   = {Digit} '.' {Digit};
DecimalNumber  = Digit {Digit};
BinaryNumber   = '%' BinaryDigit {BinaryDigit};
HexNumber      = '$' HexDigit {HexDigit};
IntegerLiteral = DecimalNumber | BinaryNumber | HexNumber;
StringLiteral  = '"' {CHARACTERS-('"' | ?EOL?)} '"';

Identifier     = Letter {'_' | Letter | Digit};
Label          = '.' Identifier;
vertex.dreamfall.at | GitHub

TheShadow

Moderator

BeitragSa, Nov 03, 2007 10:50
Antworten mit Zitat
Benutzer-Profile anzeigen
hm vertex und blitzprogger - ich stelle fest ihr verfolgt fast das gleiche Ziel Smile

mittlerweile habe ich selbst wieder lust bekommen einen neuanfang zu wagen... Smile

Allerdings würde ich es wieder in C machen - und ohne XML, Compiler-Compiler und Co.
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2
 

E. Urbach

ehemals "Basicprogger"

BeitragSa, Nov 03, 2007 13:50
Antworten mit Zitat
Benutzer-Profile anzeigen
3 Personen an 3 Projekten mit 1 Ziel...wenn das mal gut geht...

Btw, der Parser für mathematische Ausdrücke ist jetzt fertig. Ein Code wie dieser
Code: [AUSKLAPPEN]
Local a:Int = 3
Local b:Int = 4
Local c:Int = 5

Local isPythagoreanTriple:Bool = (a^2 + b^2 = c^2)

wird jetzt korrekt und bis ins Detail in einen AST umgewandelt:
Code: [AUSKLAPPEN]
<?xml version="1.0"?>

<module>
   <header>
   </header>
   <code>
      <local>
         <var name="a">
            <type>
               Int
            </type>
            <value>
               3
            </value>
         </var>
      </local>
      <local>
         <var name="b">
            <type>
               Int
            </type>
            <value>
               4
            </value>
         </var>
      </local>
      <local>
         <var name="c">
            <type>
               Int
            </type>
            <value>
               5
            </value>
         </var>
      </local>
      <local>
         <var name="isPythagoreanTriple">
            <type>
               Bool
            </type>
            <value>
               <compare>
                  <term>
                     <add>
                        <term>
                           <pow>
                              <term>
                                 a
                              </term>
                              <term>
                                 2
                              </term>
                           </pow>
                        </term>
                        <term>
                           <pow>
                              <term>
                                 b
                              </term>
                              <term>
                                 2
                              </term>
                           </pow>
                        </term>
                     </add>
                  </term>
                  <term>
                     <pow>
                        <term>
                           c
                        </term>
                        <term>
                           2
                        </term>
                     </pow>
                  </term>
               </compare>
            </value>
         </var>
      </local>
   </code>
</module>

Habe den neuen Code bereits hochgeladen, ist im Versionskontrollsystem zu finden.

Edit: Wenn's irgendwen interessiert: Bin vom kommenden Montag bis Freitag nicht mehr erreichbar weil ich nach Berlin fahre, kann also auch keine Fragen zum Code oder anderen Sachen beantworten...
The box said, "Requires Windows XP or better", so I installed Ubuntu | Linux is NOT Windows
Flua :: Profiler für BB und BMax :: Partikel-Engine für BMax :: Lyphia-Projekt Quellcode (BMax) :: Automatische Parallelisierung :: Meine Musik

Vertex

BeitragSa, Nov 03, 2007 16:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Zum Thema mathematische Ausdrücke hier einen simplen Parser:
Code: [AUSKLAPPEN]
SuperStrict

Framework BRL.Blitz

Global In       : String, ..
       Position : Int, ..
       Token    : Byte

' Test
In = "10<3^2+~~9/8*(20>2)" ' 10 Shl 3^2 + ~9/8*(20 Shr 2)

Try
   Parse()
Catch Exception:Object
   WriteStdout(Exception.ToString())
End Try

End

Function Parse:Int()
   Local Result:Int

   GetToken()
   Result = Expression()
   WriteStdout("Result: " + Result)
End Function

Function GetToken()
   If Position > In.Length - 1 Then
      Token = Asc("~n")
   Else
      Token = In[Position]
   EndIf
   Position :+ 1
End Function

Function Match(Char:Byte)
   If Token = Char Then
      GetToken()
   Else
      Throw("Expected '" + Chr(Char) + "'")
   EndIf
End Function

Function Expression:Int()
   Local Result:Int

   Result = Shift()
   While Token = Asc("+") Or Token = Asc("-")
      If Token = Asc("+")
         GetToken()
         Result = Result + Shift()
      Else
         GetToken()
         Result = Result - Shift()
      EndIf
   Wend

   Return Result
End Function

Function Shift:Int()
   Local Result:Int

   Result = Term()
   While Token = Asc(">") Or Token = Asc("<")
      If Token = Asc(">") Then
         GetToken()
         Result = Result Shr Term()
      Else
         GetToken()
         Result = Result Shl Term()
      EndIf
   Wend

   Return Result
End Function

Function Term:Int()
   Local Result:Int

   Result = Power()
   While Token = Asc("*") Or Token = Asc("/")
      If Token = Asc("*") Then
         GetToken()
         Result = Result*Power()
      Else
         GetToken()
         Result = Result/Power()
      EndIf
   Wend

   Return Result
End Function

Function Power:Int()
   Local Result:Int

   Result = Unary()
   While Token = Asc("^")
      GetToken()
      Result = Result^Unary()
   Wend

   Return Result
End Function

Function Unary:Int()
   Local Result:Int

   If Token = Asc("~~") Then
      GetToken()
      Result = ~Factor()
   Else
      Result = Factor()
   EndIf

   Return Result
End Function

Function Factor:Int()
   Local Result:Int

   If Token = Asc("(") Then
      Match(Asc("("))
      Result = Expression()
      Match(Asc(")"))
   Else
      Result = Number()
   EndIf

   Return Result
End Function

Function Number:Int()
   Local Result:Int

   While Token => Asc("0") And Token <= Asc("9")
      Result = Result*10 + Digit()
   Wend

   Return Result
End Function

Function Digit:Int()
   Local Result:Int

   If Token => Asc("0") And Token <= Asc("9") Then
      Result = Token - Asc("0")
      Match(Token)
   Else
      Throw("Expected Digit")
   EndIf

   Return Result
End Function


Vgl. zu Blitz:
Code: [AUSKLAPPEN]
Print 10 Shl 3^2 + ~9/8*(20 Shr 2)


Beide liefern 5115 als Ergebnis.

Ansonsten bin ich gerade am Ball den FreeBlitz Scanner zu schreiben aber hierzu werde ich nun C# benutzen. Wäre zwar cool, das Projekt in BlitzMax zu entwickeln, bloß ist das Debugging bei BMax mir zu bescheiden.

mfg olli
vertex.dreamfall.at | GitHub

Vertex

BeitragMi, Nov 07, 2007 23:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Joar, der FreeBlitz Scanner ist soweit fertig. Man kann in C# dann so etwas machen:
Code: [AUSKLAPPEN]
scanner = new Scanner(@"C:\Test.bb");
// scanner = new Scanner(textCode.Text);

token = scanner.NextToken();
while(token.Id != TokenId.EndOfFile)
{
   switch(token.Id)
   {
      case TokenId.IntegerLiteral:
         // token.value
         break;

      case TokenId.StringLiteral:
         // token.value
         break;

      // ...
      case TokenId.EndFunction
      // ...
   }

   token = scanner.NextToken();
}


Das ganze habe ich mal in 3 Minuten in eine Form gepappt und es funktioniert alles einwandfrei bis jetzt:
user posted image

Mal schauen, ob ich wirklich noch dazu einen Parser entwickle Smile

mfg olli

Achja: Damit muss nicht erst der ganze Quellcode gescannt werden. Es reicht praktisch ein Parser mit 2 Pässen aus. Der erste, der benötigte Tokens analysiert und der zweite, der die semantische Analyse durchführt.
vertex.dreamfall.at | GitHub
 

lettorTrepuS

BeitragDo, Nov 08, 2007 6:03
Antworten mit Zitat
Benutzer-Profile anzeigen
-aus Sicherheitsgründen gelöscht- Diese Information ist mit Ihrer Sicherheitsfreigabe leider nicht erhältlich, Bürger.
 

porcus

BeitragDo, Nov 08, 2007 15:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Wäre es nicht einfacher das ganze in BlitzMax zu machen ?
*Account deaktiviert*
 

Sebe

BeitragDo, Nov 08, 2007 18:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Dann wäre das ganze ja durch BlitzMax limitiert.
Viel interessanter fände ich sowas für .Net/Mono.

mahe

BeitragDo, Nov 08, 2007 19:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn es nicht richtig kompiliert wird kann man es gleich vergessen.

Diese ganzen virtuellen Maschinen mit ihrem seltsamen Byte-Code usw. sind für Spiele ziemlich ungeeignet (zumindest wenn es über Handy-Games hinausgehen soll).
Das ist immer langsam, vorher muss der ganze Unsinn erst einmal installiert werden und überhaupt ist das irgendwie nervig und unnötig.

Derzeit gibt es drei wichtige Plattformen (Win, Lin und Mac) und für die drei zu kompilieren ist doch nicht so ein Aufwand (siehe BMax). Für alle drei eine neue virtuelle Maschine zu erstellen wäre also unsinnig.

Wenn das ganze aber nach C(++) konvertiert wird und ordentlich kompiliert wird, kann ich mir vorstellen, dass das was wird!
ʇɹǝıdɯnɹɹoʞ ɹnʇɐuƃıs - ǝpoɥʇǝɯ-ɹoɹɹıɯ ɹǝp uı ,ɹoɹɹǝ,

Gehe zu Seite Zurück  1, 2, 3, 4  Weiter

Neue Antwort erstellen


Übersicht Sonstiges Smalltalk

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group