
Write a compiler. Some possibility?
- DoubleDutch
- Addict
- Posts: 3220
- Joined: Thu Aug 07, 2003 7:01 pm
- Location: United Kingdom
- Contact:
Its starting to look pretty good. 

https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
https://reportcomplete.com <- School end of term reports system
- DoubleDutch
- Addict
- Posts: 3220
- Joined: Thu Aug 07, 2003 7:01 pm
- Location: United Kingdom
- Contact:
Possible bug...
I entered
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:
I entered
Output:apple=orange*3
Code: Select all
apple=orange*3
mov edx, [v_ORANGE]
push edx
mov edx, 3
pop ecx
imul edx, ecx
mov v_[APPLE], edx
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
https://reportcomplete.com <- School end of term reports system
It won't compile here always gives an Assembler Error saying Purebasic.asm (1236) Add()
nvalid Operand.
nvalid Operand.
Visit www.sceneproject.org
Yes, a typo.DoubleDutch wrote:Possible bug...[/code]
You're saying that PureBasic can't compile the source to the compiler? Now that's strange, which version of PB are you using?It won't compile here always gives an Assembler Error saying Purebasic.asm (1236) Add()
nvalid Operand.
Ermm, an Agfa? I'm not quite sure what you mean.thefool wrote:yeah it does
Thanks for the tip, trond. Wich scanner are you using?

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)):jack wrote:very interesting Trond, can we see more?
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()
-
- Addict
- Posts: 1675
- Joined: Sun Dec 12, 2010 12:36 am
- Location: Somewhere in the midwest
- Contact:
Re: Write a compiler. Some possibility?
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.
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.