Page 4 of 4

Posted: Sun Dec 18, 2005 10:46 pm
by DoubleDutch
Its starting to look pretty good. :)

Posted: Sun Dec 18, 2005 10:51 pm
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 

Posted: Sun Dec 18, 2005 10:51 pm
by thefool
yeah it does :)

Thanks for the tip, trond. Wich scanner are you using?

Posted: Sun Dec 18, 2005 11:06 pm
by Nik
It won't compile here always gives an Assembler Error saying Purebasic.asm (1236) Add()
nvalid Operand.

Posted: Mon Dec 19, 2005 1:01 am
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.

Posted: Mon Dec 19, 2005 1:16 am
by Dare2
jack wrote:TronDoc passed away on november 23.
Ah no. He was a really nice bloke. :cry:

Posted: Mon Dec 19, 2005 1:22 pm
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()

Posted: Mon Dec 19, 2005 2:01 pm
by thefool
-

Posted: Mon Dec 19, 2005 2:35 pm
by Trond
Oh, AVG.

Posted: Mon Dec 19, 2005 2:53 pm
by thefool
:D

Re: Write a compiler. Some possibility?

Posted: Mon Mar 28, 2011 4:41 pm
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.