Write a compiler. Some possibility?

Everything else that doesn't fall into one of the other PB categories.
User avatar
DoubleDutch
Addict
Addict
Posts: 3220
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

Its starting to look pretty good. :)
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
User avatar
DoubleDutch
Addict
Addict
Posts: 3220
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

Possible bug...

I entered
apple=orange*3
Output:

Code: Select all

apple=orange*3
    mov edx, [v_ORANGE]
    push edx
    mov edx, 3
    pop ecx
    imul edx, ecx
    mov v_[APPLE], edx
note the "mov v_[APPLE],edx" is incorrect - shouldn't it be v_APPLE ???

Edit: Here is the (easy - must have been a typo) fix:

Code: Select all

Procedure Assignment() 
  Name.s = GetName() 
  Match("=") 
  Expression() 
  EmitLn("mov [v_" + Name.s + "], edx") 
EndProcedure 
Last edited by DoubleDutch on Sun Dec 18, 2005 10:53 pm, edited 1 time in total.
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

yeah it does :)

Thanks for the tip, trond. Wich scanner are you using?
Nik
Addict
Addict
Posts: 1017
Joined: Fri May 13, 2005 11:45 pm
Location: Germany
Contact:

Post by Nik »

It won't compile here always gives an Assembler Error saying Purebasic.asm (1236) Add()
nvalid Operand.
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Post by jack »

very interesting Trond, can we see more?
btw, at first i thought that you were TronDoc but have learned that TronDoc passed away on november 23.
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

jack wrote:TronDoc passed away on november 23.
Ah no. He was a really nice bloke. :cry:
@}--`--,-- A rose by any other name ..
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

DoubleDutch wrote:Possible bug...[/code]
Yes, a typo.
It won't compile here always gives an Assembler Error saying Purebasic.asm (1236) Add()
nvalid Operand.
You're saying that PureBasic can't compile the source to the compiler? Now that's strange, which version of PB are you using?
thefool wrote:yeah it does :)

Thanks for the tip, trond. Wich scanner are you using?
Ermm, an Agfa? I'm not quite sure what you mean. :?
jack wrote:very interesting Trond, can we see more?
Ok, here's the same code as above but extended to handle multiple lines (you need to pass them as the FIRST program parameter (do it within quotes to prevent the tokens from being separated into multiple parameters)):

Code: Select all

OpenConsole()

#Ind = "    "
#QUOTE$ = "'"
Global Look.s
Global Stream.s

;Logical not
Procedure.l Not(b.l)
  !CMP  DWord [ESP], 0
  !JZ   l_cl_0
  !XOR  eax, eax
  ProcedureReturn
  cl_0:
  !MOV  eax, 1
  ProcedureReturn
EndProcedure

;Cleanup then end
Procedure Finish()
  PrintN("")
  PrintN("Compilation finished, press a key...")
  Input()
  End
EndProcedure

;Make sure a character is a visible one
Procedure.s VisibleToken(s.s)
  Select s.s
    Case #CR$
      s.s = "newline (CR)"
    Case #LF$
      s.s = "newline (LF)"
    Case ""
      s.s = "empty string"
    Default
      s.s = #QUOTE$ + s.s + #QUOTE$
  EndSelect
  ProcedureReturn s.s
EndProcedure

;Report an error
Procedure Error(s.s)
  PrintN("Error: "+s+".")
EndProcedure

;Report an error then abort
Procedure Abort(s.s)
  Error(s.s)
  Finish()
EndProcedure

;Report what was expected and abort
Procedure Expected(expected.s)
  Abort("Expected: '" + expected + "', got " + VisibleToken(Look))
EndProcedure

;Output a tabbed string
Procedure Emit(s.s)
  Print(#Ind + s.s)
EndProcedure

;Output a tabbed line with linefeed
Procedure EmitLn(s.s)
  SetClipboardText(GetClipboardText()+s.s+Chr(13)+Chr(10))
  Emit(s.s)
  PrintN("")
EndProcedure

;Read a character into Look
Procedure GetChar()
  Look = Left(Stream,1)
  Stream = Right(Stream, Len(Stream)-1)
EndProcedure

;Match a specific input character
Declare EatWhite() ;forward
Procedure Match(*s.s)
  If Look = *s
    GetChar()
    EatWhite()
  Else
    Expected(*s)
  EndIf
EndProcedure

;Recognize an alpha character
Procedure.l IsAlpha(*s.s)
  ProcedureReturn (Asc(UCase(*s.s)) > 64 And Asc(UCase(*s.s)) < 91)
EndProcedure

;Recognize an addop
Procedure.l IsAddop(*s.s)
  ProcedureReturn (*s.s = "+" Or *s.s = "-")
EndProcedure

;Recognize a decimal digit
Procedure.l IsDigit(*s.s)
  ProcedureReturn (Asc(UCase(*s.s)) > 47 And Asc(UCase(*s.s)) < 58)
EndProcedure

;Recognize an alphanumeric
Procedure.l IsAlphaNumeric(*s.s)
  ProcedureReturn (IsAlpha(*s.s) Or IsDigit(*s.s))
EndProcedure

;Recognize whitespace
Procedure.l IsWhiteSpace(*s.s)
  Select *s.s
    Case " "
    Case #TAB$
    Default
      ProcedureReturn 0
  EndSelect
  ProcedureReturn 1
EndProcedure

;Recognize a newline
Procedure.l IsNewline(*s.s)
  ProcedureReturn ((*s.s = #CR$) Or (*s.s = #LF$))
EndProcedure

;Get an identifier
Procedure.s GetName()
  temp.s = ""
  If Not(IsAlpha(Look))
    Expected("Name")
  EndIf
  While IsAlphaNumeric(Look)
    temp + UCase(Look)
    GetChar()
  Wend
  EatWhite()
  ProcedureReturn temp
EndProcedure

;Get a number
Procedure.s GetNum()
  temp.s = ""
  If Not(IsDigit(Look))
    Expected("Integer")
  EndIf
  While IsDigit(Look)
    temp + Look
    GetChar()
  Wend
  EatWhite()
  ProcedureReturn temp
EndProcedure

;Skip whitespace
Procedure EatWhite()
  While IsWhiteSpace(Look)
    GetChar()
  Wend
EndProcedure

;Skip newlines
Procedure EatLines()
  While IsNewline(Look)
    GetChar()
  Wend
EndProcedure

;Skip whitespace and newlines
Procedure EatBlank()
  While IsWhiteSpace(Look) Or IsNewline(Look)
    EatWhite()
    EatLines()
  Wend
EndProcedure

;Init
Procedure Init()
  SetClipboardText("")
  Stream = ProgramParameter()
  If Stream = ""
    PrintN("No parameter. Type in your program:")
    Stream = Input()+#CR$ : PrintN("")
  EndIf
  Stream = ReplaceString(Stream, #CRLF$, #CR$)
  GetChar()
  EatBlank()
EndProcedure

;------------------------------
;D0 D1 = edx, ecx

Declare Expression() ;forward declaration for factor

;Parse and translate an identifier
Procedure Identifier()
  Name.s
  Name = GetName()
  If Look = "("
    Match("(")
    Match(")")
    EmitLn("call [f_" + Name + "]")
    EmitLn("mov edx, eax")
  Else
    EmitLn("mov edx, [v_" + Name + "]")
  EndIf
EndProcedure

;Parse and translate a math factor
Procedure Factor()
  If Look = "("
    Match("(")
    Expression()
    Match(")")
  ElseIf IsAlpha(Look)
    Identifier()
  Else
    EmitLn("mov edx, " + GetNum())
  EndIf
EndProcedure

;Recognize and translate a multiply
Procedure Multiply()
  Match("*")
  Factor()
  EmitLn("pop ecx")
  EmitLn("imul edx, ecx")
EndProcedure

;Recognize and translate a divide
Procedure Divide()
  Match("/")
  Factor()
  EmitLn("pop eax")
  EmitLn("mov ecx, edx")
  EmitLn("xor edx, edx")
  EmitLn("idiv ecx")
  EmitLn("mov edx, eax")
EndProcedure

;Parse and translate a math term
Procedure Term()
  Factor()
  While Look = "*" Or Look = "/"
    EmitLn("push edx")
    Select Look
      Case "*" : Multiply()
      Case "/" : Divide()
    EndSelect
  Wend
EndProcedure

;Parse and translate an add
Procedure Add()
  Match("+")
  Term()
  EmitLn("pop ecx")
  EmitLn("add edx, ecx")
EndProcedure

;Parse and translate a subtract
Procedure Subtract()
  Match("-")
  Term()
  EmitLn("pop ecx")
  EmitLn("sub edx, ecx")
  EmitLn("neg edx")
EndProcedure

;Parse and translate an expression
Procedure Expression()
  If IsAddop(Look)
    EmitLn("xor edx,edx")
  Else
    Term()
  EndIf
  While IsAddop(Look)
    EmitLn("push edx")
    Select Look
      Case "+" : Add()
      Case "-" : Subtract()
    EndSelect
  Wend
EndProcedure

;Parse and translate an assignment statement
Procedure Assignment()
  Name.s = GetName()
  Match("=")
  Expression()
  EmitLn("mov [v_" + Name.s + "], edx")
EndProcedure

;Parse and translate a program
Procedure Program()
  Repeat
    Assignment()
    EatBlank()
  Until Look = ""
  If Look <> ""
    Expected("Nothing")
  EndIf
EndProcedure

;------------------------------

Init()
Program()
;If Look <> #CR$ : Expected("Newline") : EndIf

;Print(Stream)
Finish()
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

-
Last edited by thefool on Wed Apr 20, 2011 6:45 pm, edited 1 time in total.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Oh, AVG.
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

:D
Zach
Addict
Addict
Posts: 1675
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: Write a compiler. Some possibility?

Post by Zach »

Sorry to necro this thread, but I was doing a search to see if anyone had setup PB to compile through Netbeans and this thread was in the results..

I don't know how slow it was years ago but within the past year or two I had used it while playing around with learning some Python and I found it to be quite fast and reasonable.. I've used Vuze in the past as well (formerly known as Azureus, the Bit Torrent Client) and it seemed plenty fast to me. There is also a Power-Post type clone (batch Poster for Usenet), I forget what its called, but it was plenty fast as well, although it is a relatively "simple" type of application...


However I really did like Netbeans as an IDE and I was wondering if it is possible to set it up to work with the PB compiler / debugger? Of course getting Syntax Highlighting would be its own challenge but I would set that point aside from the "does it work at all?" question.
Post Reply