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

http://www.purebasic.com
https://www.purebasic.fr/english/
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
Code: Select all
Procedure Assignment()
Name.s = GetName()
Match("=")
Expression()
EmitLn("mov [v_" + Name.s + "], edx")
EndProcedure
Ah no. He was a really nice bloke.jack wrote:TronDoc passed away on november 23.
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()