###################################################################### # # *** IMPORTANT *** : Please do not submit or publish any additions # or improvements to this or other files just yet. # These files will likely be open source. # However, details have not been worked out yet. # Please do not submit bug reports yet either. # This beta is a snap shot with many missing or # evolving pieces, so it is already expected that # certain things won't work as anticipated. # # Basic.uc: This is a PowerBASIC-flavored version of BASIC, with a # sample subset of features. uCalcLB.dll was compiled with # PB/Win 9.01. uCalc and PowerBASIC are otherwise not # affiliated. PowerBASIC is a trademark of PowerBASIC, Inc. # # For the real PowerBASIC, which compiles optimized Exe and # DLL files, and contains a host of other featers, please # visit: www.powerbasic.com # # For use with uCalc Language Builder v ??? # # Code in this file originally written by: Daniel Corbier # Contact: support at ucalc.com # Date: ??? # # Revision: ??? Date: ??? By: ??? contact: ??? # Modifications: ???, ???, ??? # ###################################################################### Pass: 5 Include: uCalc.uc Include: Graphics.uc CodePrefix: CrLf CodePostfix: CrLf Pattern: ' Pattern: ; ~~ Properties: ucArgSeparator Pattern: : ~~ Properties: ucStatementSep Pattern: \r\n ~~ Properties: ucStatementSep Pattern: [$%]?[a-z][0-9a-z_]* ~~ Properties: ucAlphaNumeric Pattern: [a-z_][0-9a-z_]*[%&?!#@$]{1,3} ~~ Properties: ucAlphaNumeric # Items that are renamed twice are for overloaded versions of the function or operator Rename: "==" "=", "==" "=", "Rand" "Rnd", "Rand" "Rnd", "Atan" "Atn" Rename: "TrimRight" "RTrim$", "TrimLeft" "LTrim$", "Trim" "Trim$" Rename: "Extract" "Extract$", "Extract" "Extract$", "Remain" "Remain$", "Remain" "Remain$" Rename: "LowerCase" "LCase$", "UpperCase" "UCase$", "Mid" "Mid$", "Left" "Left$", "Right" "Right$" Synonym(Pass 2): Asciiz LPCSTR, Ext Extended, Quad Int64, Peek ValueAtAddr, Local Dim Synonym(Pass 2): Max$ Max, Min$ Min, Peek$ uc_Peek, Let SyntaxArgL: {specifier} = "{specifier:{q}[%&?!#@$]{1,3}{q}}" Var: _x Var: _DimAll Var: _DType(255) As String Var: _FileHandle(255) As Dword Var: _vName As String = "[ ]*@*[a-z_][0-9a-z_.]*[%&?!#@$]*" Pass: 1 Syntax: _ {cr} ::= Syntax: ? ::= Print{sp} Syntax: {Comment:"'.*"} ::= Syntax: {Comment:"REM .*"} ::= Syntax: {cr}{" *%"}{NumConst:"[a-z][0-9a-z]*"} = {Val} ::= ~Define(Const: %{NumConst} = {Val}) Syntax: {cr}{" *[\$]"}{StrConst:"[a-z][0-9a-z]*"} = {Val} ::= ~Define(Const: ${StrConst} As String = {Val}) Syntax: {start: Then | Else | Let | : | {cr}} {VarName:_vName}[({subscript})] = {value} {stop: Else | : | {cr}} _ ::= {start} SetVar({VarName}{subscript:({subscript})}, {value}) {stop} Syntax: {Prog_Start} ::= {cr} Syntax: {Prog_Start} > {Debug:".*"} ::= ucExpand({q}{Debug}{q}) Syntax: {Prog_Start} >> {Debug:".*"} ::= ucSteps({q}{Debug}{q}) Syntax: {Prog_Start} >>> ::= SkipOver ~~ Syntax: Data {List:".+"} Syntax: Func: {FuncName:_sAlpha}[{specifier}]([{args}]) = _ ::= Func: {FuncName}{specifier}({args}) As _SType({specifier}) = Syntax: {Quote:"\q[^\q\r]*"}{"\r\n"} ::= {Quote}{dq}{cr} Syntax: {Quote:"\q"}{Text:"[^\q\r]*"}{"\q\q"} ::= "{Text}"+Chr(34)+{dq} Syntax: Global {variables:".*"} ::= ~Eval(Dim {variables}) Syntax: DefByt {range} ::= _DefType Byte {range} Syntax: DefCur {range} ::= _DefType Currency {range} Syntax: DefDbl {range} ::= _DefType Double {range} Syntax: DefDwd {range} ::= _DefType Dword {range} Syntax: DefExt {range} ::= _DefType Extended {range} Syntax: DefInt {range} ::= _DefType Integer {range} Syntax: DefLng {range} ::= _DefType Long {range} Syntax: DefQud {range} ::= _DefType Int64 {range} Syntax: DefSng {range} ::= _DefType Single {range} Syntax: DefStr {range} ::= _DefType String {range} Syntax: DefWrd {range} ::= _DefType Word {range} Syntax: _DefType {Type:1} {char} ::= ~Eval(SetVar(_DType(Asc(LCase$("{char}"))), "{Type}")) Syntax: _DefType {Type:1} {ch1}-{ch2} ::= ~Eval(uc_For(_x, Asc(LCase$("{ch1}")), Asc(LCase$("{ch2}")), 1, SetVar(_DType(_x), "{Type}"))) Syntax: _DefType {Type:1} {arg}, {etc} ::= _DefType {Type} {arg} {cr} _DefType {Type} {etc} Syntax: Option Explicit ::= #Dim All Syntax: #Dim All ::= ~Eval(SetVar(_DimAll, ucTrue)) Syntax: #Dim None ::= ~Eval(SetVar(_DimAll, ucFalse)) Syntax: #If {condition} {cr} _ {Statements+} {cr} _ [#Else {cr} _ {StatementsB+}{cr}] _ #EndIf _ ::= ~Eval(iif({condition}, {q}{Statements}{q}+CrLf, {q}{StatementsB}{q}+CrLf)) Syntax: #Include {FileName} ::= ~FileInclude{FileName} Syntax: #Console On ::= LoadConsole("uCalc LB BASIC Console") Syntax: #Console Off ::= FreeConsole Pass: 2 Syntax: Macro {Def} ::= ~Define(Macro: {Def}) Syntax: Declare Sub {name} [Lib {libname}] [([{arglist}])] _ ::= ~Define(Func: {name}({arglist}) As Void _ At GetProcAddress(LoadLibrary({libname}), "{name}")) Syntax: Declare Sub {name} Lib {libname} Alias {aliasname} [([{arglist}])] _ ::= ~Define(Func: {name}({arglist}) As Void _ At GetProcAddress(LoadLibrary({libname}), {aliasname})) Syntax: Declare Function {name} [Lib {libname}] [([{arglist}])] [As {type}] _ ::= ~Define(Func: {name}({arglist}) {type: As {type}} _ At GetProcAddress(LoadLibrary({libname}), "{name}")) Syntax: Declare Function {name} Lib {libname} Alias {aliasname} [([{arglist}])] [As {type}] _ ::= ~Define(Func: {name}({arglist}) {type: As {type}} _ At GetProcAddress(LoadLibrary({libname}), {aliasname})) Syntax: Sub {SubName:1}[([{args}])] {cr} _ {Statements+} {cr} _ End Sub _ ::= ~Define(Func: {SubName}({args}) As Void = {Statements}) _ ~Define(Syntax: {SubName}{"[ ]+"}{argl} ::= {SubName}({argl})) Syntax: Function {FuncName:1}[([{args}])] {As {type} {cr} | {IfNoType: {cr}}} _ {Statements+} {cr} _ End Function _ ::= ~Define({ Syntax: SetVar({Function | {FuncName}}, {Value}) ::= SetVar(_ReturnVal, {Value}) } ~~ _ Func: {FuncName}({args}) {type: As {type}} = _ ~Local(Var: _ReturnVal As {type} {IfNoType: ~Expand(_SType({FuncName}))}) _ {Statements}{cr} _ReturnVal) _ ~Define(Syntax: {FuncName}{"[ ]+"}{argl} ::= {FuncName}({argl})) Syntax: Function PBMain [()] [As Long] {cr} _ {Statements+} {cr} _ End Function _ ::= {Statements} Syntax: Type {UserType} {cr} _ {Members+} {cr} _ End Type _ ::= ~Local(DataType: {UserType} ~~ MemberList: {Members} {cr} TypeHandler: @uc_User_Type) Syntax: Union {UserType} {cr} _ {Members+} {cr} _ End Union _ ::= ~Local(DataType: {UserType} ~~ IsUnion ~~ MemberList: {Members} {cr} TypeHandler: @uc_User_Type) Syntax: MemberList: [{Member}] {cr} ::= { Var: {Member} } ~~ MemberList: Syntax: MemberList: TypeHandler: ::=TypeHandler: SkipOver ~~ Syntax: Data {List:".+"} Syntax: Data {ListA:".+"} {cr} _ [{OtherLines+} {cr}] _ Data {ListB:".+"} _ ::= _ {OtherLines} {cr} _ Data {ListA}, {ListB} Pass: 3 Syntax: Call Dword {Addr} Using {ProcName}[({args})] [To {result}] ::= _ uCalc(uc_SetItemData, "{ProcName}", 0, uc_Address, {Addr}) : _ ~Expand({result: {result} = } {ProcName}({args})) Syntax: Static {Item} ::= ~Static(Var: {Item}) {cr} Syntax: Static {FirstVar}, {OtherVars} ::= Static {FirstVar} {cr} Static {OtherVars} {cr} Syntax: Dim {Item} ::= ~Local(Var: {Item}) {cr} Syntax: Dim {FirstVar}, {OtherVars} ::= Dim {FirstVar} {cr} Dim {OtherVars} {cr} Syntax: If {cond} Then {Statements1:" +.+"} ::= IfElseIf({cond}, ({Statements1}:)) : Syntax: If {cond} Then {Statements1} Else {Statements2:" +.+"} ::= IfElseIf({cond}, ({Statements1}:), 1, ({Statements2}:)) : SkipOver ~~ Syntax: If {cond} Then {cr} PassOnce ~~ Syntax: Data {List:".+"} ::= _ Eval(Static DataCount) _ Eval(Static Read$(~Eval(ArgCount({List})))) _ Data {List} Pass: 4 SkipOver ~~ Syntax: Graphic Print {text} PassOnce ~~ Syntax: Print [{data}] ::= Print {data}; : WriteLn() SkipOver ~~ Syntax: Print [{data>}] { , || ; } { : | {cr} } PassOnce ~~ Syntax: Print #{filenum}, [{data}] ::= Print #{filenum}, {data}; : WriteLn(_FileHandle({filenum})) SkipOver ~~ Syntax: Print #{filenum}, [{data>}] { , || ; } { : | {cr} } Syntax: Eval({Statements}) ::= ~Eval({Statements}) Syntax: Data {Item} ::= ~Eval(DataCount=DataCount+1 : Read$(DataCount) = {q}{Item}{q} : "") Syntax: Data {Item:" +[\q][^\q]*[\q]"} ::= ~Eval(DataCount=DataCount+1 : Read$(DataCount) = {Item} : "") Syntax: Data {FirstItem}, {OtherItems} ::= Data {FirstItem} {cr} Data {OtherItems} Pass: 5 Syntax: _SType() ::= Extended Syntax: _SType(%) ::= Integer Syntax: _SType(&) ::= Long Syntax: _SType(?) ::= Byte Syntax: _SType(??) ::= Word Syntax: _SType(???) ::= DWord Syntax: _SType(!) ::= Single Syntax: _SType(#) ::= Double Syntax: _SType(##) ::= Extended Syntax: _SType(@) ::= Currency Syntax: _SType($) ::= String Syntax: _SType({Name:"[a-z0-9_]+"}[{Specifier}]) ::= _SType({Specifier}) Execute: uc_For(_x, 0, 255, 1, SetVar(_DType(_x), "Extended")) Syntax: Var: {VarName:1} As String * {Size} ::= Variable ~~ Name: {VarName} ~~ DataType: FixedString ~~ Size: {Size} Syntax: Var: {VarName:1} As {Type:1} Ptr ::= Variable ~~ Name: {VarName} ~~ DataType: Dword _ ~~ NextDef ~~ Precedence: 100 _ ~~ Syntax: @{VarName} [ "["{Index=0}"]" ] ::= ValueAtAddr({Type}, {VarName}, {Index}) Syntax: Var: {VarName:_sAlpha}{specifier} ::= Var: <_SType({specifier})>{VarName}{specifier} Syntax: Var: {VarName:1} ::= Var: <~Eval(_DType(Asc(LCase$("{VarName}"))))>{VarName} Precedence: (Precedence(">") + Precedence("And")) / 2 Syntax: NOT {expr#} ::= (0 - ({expr}) - 1) Syntax: IsTrue {expr#} ::= (({expr}) <> 0) Syntax: IsFalse {expr#} ::= (({expr}) = 0) Precedence: 100 Syntax: &{"b"}{BinaryNumber:"[0-1]+"} ::= ~Eval(BaseConvert("{BinaryNumber}", 2)) Syntax: &{"o"}{OctalNumber:"[0-7]+"} ::= ~Eval(BaseConvert("{OctalNumber}", 8)) Syntax: &{"h"}{HexNumber:"[0-9A-F]+"} ::= ~Eval(BaseConvert("{HexNumber}", 16)) Precedence: 5 Syntax: Print ::= Syntax: Print {data} ::= Write(_ToStr({data})) Syntax: Print , ::= NextPrintZone() Syntax: Print ; ::= Syntax: Print {data#} {more#} ::= Print {data} : Print {more} Syntax: Print #{filenum}[,] ::= Syntax: Print #{filenum}, {data} ::= Write(_FileHandle({filenum}), _ToStr({data})) #Syntax: Print #{filenum}, , ::= NextFilePrintZone() +++ Syntax: Print #{filenum}, ; ::= Syntax: Print #{filenum}, {data#} {more#} ::= Print #{filenum}, {data} : Print #{filenum}, {more} Precedence: 10 Syntax: For {x} = {start} To {stop} [Step {i=1}] { : | {cr} } _ {Statements+} _ Next _ ::= uc_For({x}, {start}, {stop}, {i}, ({Statements})) Syntax: While {cond} { : | {cr} } _ {Statements+} _ Wend _ ::= uc_Loop(({cond}), ({Statements}), 1) Syntax: Do [While {DoCond=1}] {cr} _ {Statements+} _ Loop [{While {LoopCond=1} | Until {UntilCond} }] _ ::= uc_Loop(({DoCond}), ({Statements}), ({LoopCond}{UntilCond: -1 + (({UntilCond}) = 0)})) # +++ Simplify (remove when possible) redundant line below Syntax: Do [While {DoCond=1}] : {Statements+} : Loop [{While {LoopCond=1} | Until {UntilCond} }] _ ::= uc_Loop(({DoCond}), ({Statements}), ({LoopCond}{UntilCond: -1 + (({UntilCond}) = 0)})) Syntax: Do Until {cond} ::= Do While ({cond}) = 0 Syntax: If {cond1} Then _ {Statements1+} _ [Else _ {Statements2+}] _ End If _ ::= IfElseIf({cond1}, ({Statements1}){Statements2:, 1, ({Statements2})}) Syntax: If {cond1} Then _ {Statements1+} _ ElseIf {cond2} Then _ {Statements2+} _ End If _ ::= ~Expand(_JoinIf({cond1}, ({Statements1}), ~Expand(If {cond2} Then {Statements2} End If))) Syntax: Select Case {sel} {cr} _ Case {TestList} { : | {cr} } _ {Statements+} _ [Case {etc+} ] _ End Select _ ::= ~Expand(_JoinIf(_Select {sel}; {TestList};, ({Statements}), _ ~Expand(Select Case {sel} {cr} {etc: Case {etc} {cr}} End Select))) Syntax: Select Case [{sel}] {cr} _ [Case Else {cr} _ {Statements+=0} {cr}] _ End Select _ ::= IfElseIf(1, ({Statements})) # This last one allows Case clauses that have no statements Syntax: Select Case {sel} {cr} _ Case {TestList} { : | {cr} } _ {Nothing:"[ \r\n]+"} _ Case _ ::= _ Select Case {sel} {cr} _ Case {TestList} {cr} _ 0 {cr} _ Case Syntax: _Select {sel}; [is]{Item}; ::= {sel} = {Item} Syntax: _Select {sel}; {min} to {max}; ::= {sel} >= {min} and {sel} <= {max} Syntax: _Select {sel}; {op:" *[<>]"} {val}; ::= {sel} {op} {val} Syntax: _Select {sel}; {first}, {other}; ::= _Select {sel}; {first}; Or _Select {sel}; {other}; Syntax: _JoinIf({cond1}, {Statements1}, IfElseIf({elseif})) ::= IfElseIf({cond1}, {Statements1}, {elseif}) Syntax: Locate {row} [, {col=CursorX}] _ ::= SetVar(_Coord.x, {col}-1) : SetVar(_Coord.y, {row}-1) : SetConsoleCursorPosition(StdOut, _Coord) : Syntax: Locate , {col} _ ::= SetVar(_Coord.x, {col}-1) : SetVar(_Coord.y, CursorY-1) : SetConsoleCursorPosition(StdOut, _Coord) : Syntax: Line Input [{Prompt:"[ ]+\q[^\q]*\q"}] [,] {StringVar} _ ::= {Prompt: Write({Prompt}) : } SetVar({StringVar}, ReadLine_FromConsole()) Syntax: Line Input #{filenum}, {variable} ::= SetVar({variable}, ReadLine_FromFile(_FileHandle({filenum}))) Syntax: Open {filespec} _ { For {{Input: Input}|{Output: Output}|{Append: Append}|{Binary: Binary}|{Random: Random}}|{Default: } } _ { Access Read | Access Write | Access Read Write | } _ { Lock {{LockRead: Read}|{LockWrite: Write}|{LockBoth: Read Write}|{LockShared: Shared}}|{LockDefault: } } _ As [#]{filenum} [Len = {size=128}] ::= _ SetVar(_FileHandle({filenum}), CreateFile( _ {filespec}, _ {Input: GENERIC_READ}{Output: GENERIC_WRITE}{Append: GENERIC_WRITE} _ {Binary: GENERIC_ALL}{Random: GENERIC_ALL}{Default: GENERIC_ALL}, _ {LockRead: FILE_SHARE_WRITE}{LockWrite: FILE_SHARE_READ}{LockBoth: 0} _ {LockShared: FILE_SHARE_READ Or FILE_SHARE_WRITE}{LockDefault: 0}, _ 0, _ {Input: OPEN_EXISTING}{Output: CREATE_ALWAYS}{Append: OPEN_ALWAYS} _ {Binary: OPEN_ALWAYS}{Random: OPEN_ALWAYS}{Default: OPEN_ALWAYS}, _ FILE_ATTRIBUTE_NORMAL, _ 0 _ )) {Append: : SetFilePointer(_FileHandle({filenum}), 0, 0, FILE_END)} Syntax: Close [#]{filenum} ::= CloseHandle(_FileHandle({filenum})) : _FileHandle({filenum}) = 0 Syntax: Get$ [#]{filenum}, {count}, {sVar} ::= _ ReadFile(_FileHandle({filenum}), _lpText, {count}, _Ignore, 0) : SetVar({sVar}, _lpText) Syntax: Put$ [#] {filenum}, {string_expression} ::= Write(_FileHandle({filenum}), {string_expression}) Syntax: Seek [#] {filenum}, {position} ::= SetFilePointer(_FileHandle({filenum}), {position}-1, 0, FILE_BEGIN) Syntax: Seek([#] {filenum}) ::= SetFilePointer(_FileHandle({filenum}), 0, 0, FILE_CURRENT)+1 Syntax: LOF({filenum}) ::= GetFileSize(_FileHandle({filenum}), 0) Syntax: EOF({filenum}) ::= IIf(Seek({filenum}) = LOF({filenum})+1, -1, 0) Func: _TextOut(ByVal hdc As Dword, ByVal text$) = TextOut(hdc, 0, 0, StrPtr(text$), Len(text$)) Syntax: ResetPen _ ::= DeleteObject(Pen_) : _ SetVar(Pen_, CreatePen(PenStyle_, PenWidth_, PenColor_)) : _ SelectObject(hdc_, Pen_) Syntax: Graphic Attach {hWin}, {id} _ ::= SetVar(hdc_, GetDC({hWin})) : _ SetVar(Pen_, CreatePen(PenStyle_, PenWidth_, PenColor_)) : _ SelectObject(hdc_, Pen_) : SetTextAlign(hdc_, 1) : _ GetTextExtentPoint32(hdc_, StrPtr(_vName), 1, VarPtr(Point_)) : _ SetVar(CharHeight_, Point_.y) : SetBkColor(hdc_, &H808080) Syntax: Graphic Color {foreground} [, {background}] _ ::= SetVar(PenColor_, {foreground}) : _ SetTextColor(hdc_, {foreground}) : _ {background: SetBkColor(hdc_, {background}) : } _ ResetPen Syntax: Graphic Line [[{Step1: Step}] ({x1}, {y1})] - [{Step2: Step}] ({x2}, {y2}) [, {rgbColor}] _ ::= {rgbColor: SetVar(PenTmp_, CreatePen(PenStyle_, PenWidth_, {rgbColor})) : _ SelectObject(hdc_, PenTmp_) : } _ {Step1: GetCurrentPositionEx(hdc_, VarPtr(Point_)) : } _ {x1: MoveToEx(hdc_, {x1}{Step1: + Point_.x}, {y1}{Step1: + Point_.y}, VarPtr(Point_)) : } _ {Step2: GetCurrentPositionEx(hdc_, VarPtr(Point_)) : } _ LineTo(hdc_, {x2}{Step2: + Point_.x}, {y2}{Step2: + Point_.y}) _ {rgbColor: : DeleteObject(PenTmp_) : SelectObject(hdc_, Pen_) } Syntax: Graphic Print {expr} _ ::= _TextOut(hdc_, _ToStr({expr})) : _ GetCurrentPositionEx(hdc_, VarPtr(Point_)) : _ SetVar(Point_.x, 0) : _ SetVar(Point_.y, Point_.y + CharHeight_) : _ MoveToEx(hdc_, Point_.x, Point_.y, VarPtr(Point_)) Syntax: Graphic Print {expr}; ::= _TextOut(hdc_, _ToStr({expr})) Syntax: Graphic Print {expr}; {other} ::= Graphic Print {expr}; : Graphic Print {other} Syntax: Graphic Style {linestyle} ::= SetVar(PenStyle_, {linestyle}) Syntax: Graphic Width {Width} ::= SetVar(PenWidth_, {Width}) : ResetPen Syntax: Graphic Window {caption}, {x}, {y}, {nWidth}, {nHeight} TO {hWin} _ ::= SetVar({hWin}, CreateWindowEx(0, "MDIClient", {caption}, _ WS_Visible+WS_OverlappedWindow, {x}, {y}, {nWidth}, {nHeight}, _ 0, 0, 0, VarPtr(CLIENTCREATESTRUCT_))) # To Do: add height of title bar? to {nHeight} of Graphic Window to match PB behavior +++ Syntax: Reset {variable}[()] ::= ResetVariable({variable}) Syntax: Reset {Var1}, {OtherVars} ::= Reset {Var1} {cr} Reset {OtherVars} {cr} Syntax: Timer ::= (GetTickCount/1000) Func: Chr$(x&) = Chr(x&) Func: Chr$(text$) As String = text$ Syntax: Chr$({Start} To {Finish}) ::= ChrRange({Start}, {Finish}) Syntax: Chr$({first}, {rest}) ::= Chr$({first}) + Chr$({rest}) Func: MsgBox(Text$, Style&=0, Title$="uCalc") As Long = MessageBox(0, Text$+"", Title$+"", Style&) Func: LoadLibrary() As Dword = 0 Func: CBYT(Byval x As Ext) As Byte = x Func: CDWD(Byval x As Ext) As Dword = x Func: CEXT(Byval x As Ext) As Extended = x Func: CCUR(Byval x As Ext) As Currency = x Func: CDBL(Byval x As Ext) As Double = x Func: CINT(Byval x As Ext) As Integer = x Func: CLNG(Byval x As Ext) As Long = x Func: CSNG(Byval x As Ext) As Single = x Func: CQUD(Byval x As Ext) As Int64 = x Func: CWRD(Byval x As Ext) As Word = x Func: MkDwd$(ByVal vDword As Dword) = Peek$(VarPtr(vDword), 4) Func: CvDwd(ByVal StrValue$) = Peek(Dword, StrPtr(StrValue$)) Syntax: Sleep {" "} {Arg} ::= Sleep({Arg}) Syntax: MsgBox {" "} {Args} ::= MsgBox({Args}) Syntax: ucDefine {" "} {Args} ::= ucDefine({Args}) Func: Str$(ByVal Value As Extended) = IIf(Value < 0, Str(Value), " " + Str(Value)) Func: _ToStr(ByVal Value As OmniType) As String = Value Func: _ToStr(ByVal Value As Extended) As String = Str$(Value) + " " Func: _ToStr(ByVal Value As String) As String = Value Func: ConsName$() = ~Local(Var: ConsName_ As Asciiz * 200) : GetConsoleTitle(ConsName_, 150) : ConsName_ Syntax: Console Name {ConsoleName} ::= SetConsoleTitle(_ToStr({ConsoleName})) Syntax: Instr([{n=1},] {Main}, ANY {Match}) ::= InStrAny({n}, {Main}, {Match}) Default ~~ ByRef ErrorHandler: _ErrorHandler(uCalc(uc_GetErrorNumber), uCalcStr(uc_GetSymbol), ~t) Mode: Execute Function InKey$() ReadConsoleInput(StdIn, _InputRecord, 1, _Ignore) If _InputRecord.EventType = KEY_EVENT _ And _InputRecord.Event.bKeyDown <> 0 _ Then InKey$ = Chr$(_InputRecord.Event.uChar) ' +++ To Do: Add mouse & extended keys later End Function Function WaitKey$() Do ReadConsoleInput(StdIn, _InputRecord, 1, _Ignore) Loop Until _InputRecord.EventType = KEY_EVENT And _InputRecord.Event.bKeyDown <> 0 WaitKey$ = Chr$(_InputRecord.Event.uChar) ' +++ To Do: Add mouse & extended keys later End Function Function FreeFile() As Long Dim x As Long Do x = x + 1 Loop Until _FileHandle(x) = 0 _FileHandle(x) = -1 FreeFile = x End Function Function Tab(ByVal n As Extended) As String _Coord.x = Max(0, n - 1) _Coord.y = CursorY - 1 If n > ScreenX Then _Coord.x = _Coord.x Mod ScreenX If n < CursorX or n > ScreenX Then _Coord.y = _Coord.y + 1 SetConsoleCursorPosition(StdOut, _Coord) End Function Function Spc(ByVal n As Extended) As String _Coord.x = CursorX-1 + (n Mod ScreenX) _Coord.y = CursorY-1 + (CursorX+n) \ ScreenX SetConsoleCursorPosition(StdOut, _Coord) End Function Function _ErrorHandler(ByVal ErrorNumber As Long, ByVal SymbolName$, ByVal t As Long) As Long If _DimAll = ucFalse And ErrorNumber = uc_Err_Undefined_Identifier Then If UCase$(Right$(SymbolName$, 1)) = LCase$(Right$(SymbolName$, 1)) _ Then ucDefine("Var: " + SymbolName$, t) _ Else ucDefine("Var: " + SymbolName$ + " As " + _DType(Asc(LCase$(SymbolName$))), t) _ErrorHandler = ucResume End If End Function #Console On ' The following loads an interpreter if there is no additional file REPL_Language = "BASIC" REPL_Startup = "Startup.Bas" REPL_OR_FILE