Initial Commit
This commit is contained in:
45
rcbasic_build/cbc_spec.txt
Normal file
45
rcbasic_build/cbc_spec.txt
Normal file
@@ -0,0 +1,45 @@
|
||||
CBC VERSION 4 SPECIFICATION
|
||||
--------------------------------
|
||||
|
||||
FIELD SIZE
|
||||
-----------------------------------
|
||||
RC4[XX] 5 bytes
|
||||
|
||||
|
||||
//----TYPE HEADER-----
|
||||
UTYPE_COUNT 8 bytes
|
||||
|
||||
//----EACH TYPE------
|
||||
FIELD_COUNT 8 BYTES
|
||||
|
||||
//----EACH FIELD----
|
||||
FIELD_TYPE 8 BYTES
|
||||
* NUMBER = 0
|
||||
* STRING = 1
|
||||
* USER = 2
|
||||
FIELD_UTYPE 8 BYTES
|
||||
FIELD_DIMENSIONS 8 BYTES
|
||||
|
||||
|
||||
//----PROGRAM HEADER-----
|
||||
N REGISTER COUNT 8 BYTES
|
||||
S REGISTER COUNT 8 BYTES
|
||||
U REGISTER COUNT 8 BYTES
|
||||
|
||||
N STACK SIZE 8 BYTES
|
||||
S STACK SIZE 8 BYTES
|
||||
U STACK SIZE 8 BYTES
|
||||
|
||||
LOOP STACK SIZE 8 BYTES
|
||||
|
||||
NUM ID COUNT 8 BYTES
|
||||
STRING ID COUNT 8 BYTES
|
||||
USER ID COUNT 8 BYTES
|
||||
|
||||
CODE SEGMENT SIZE 8 BYTES
|
||||
DATA SEGMENT SIZE 8 BYTES
|
||||
|
||||
|
||||
//----PROGRAM----
|
||||
CODE SEGMENT CODE SEGMENT SIZE
|
||||
DATA SEGMENT DATA SEGMENT SIZE
|
||||
35
rcbasic_build/constants.h
Normal file
35
rcbasic_build/constants.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef CONSTANTS_H_INCLUDED
|
||||
#define CONSTANTS_H_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct rc_user_constant
|
||||
{
|
||||
string const_name;
|
||||
vector<string> const_tokens;
|
||||
};
|
||||
|
||||
vector<rc_user_constant> rc_constants;
|
||||
|
||||
int create_constant(string c_name)
|
||||
{
|
||||
for(int i = 0; i < rc_constants.size(); i++)
|
||||
{
|
||||
if(rc_constants[i].const_name.compare(c_name)==0)
|
||||
return -1; //constant already exists
|
||||
}
|
||||
int const_id = rc_constants.size();
|
||||
|
||||
rc_user_constant c;
|
||||
c.const_name = c_name;
|
||||
|
||||
rc_constants.push_back(c);
|
||||
return const_id;
|
||||
}
|
||||
|
||||
void add_const_token(int c_id, string c_token)
|
||||
{
|
||||
rc_constants[c_id].const_tokens.push_back(c_token);
|
||||
}
|
||||
|
||||
#endif // CONSTANTS_H_INCLUDED
|
||||
516
rcbasic_build/embedded_functions.bas
Normal file
516
rcbasic_build/embedded_functions.bas
Normal file
@@ -0,0 +1,516 @@
|
||||
'StringFill
|
||||
'Stack_Size_N
|
||||
'Stack_Size_S
|
||||
'Text I/O
|
||||
sub FPrint(txt$)
|
||||
function Input$(prompt$)
|
||||
'Arrays
|
||||
function ArrayDim(Byref id)
|
||||
function StringArrayDim(Byref id$)
|
||||
function NumberArrayDim(Byref id)
|
||||
function ArraySize(Byref id, array_dim)
|
||||
function StringArraySize(Byref id$, array_dim)
|
||||
function NumberArraySize(Byref id, array_dim)
|
||||
'Math
|
||||
function Abs(n)
|
||||
function ACos(n)
|
||||
function AndBit(a,b)
|
||||
function ASin(n)
|
||||
function ATan(n)
|
||||
function Bin$(n)
|
||||
function CInt32(i)
|
||||
function CInt64(i)
|
||||
function Cos(n)
|
||||
function Degrees(r)
|
||||
function Exp(n)
|
||||
function Frac(n)
|
||||
function Hex$(n)
|
||||
function HexVal(n$)
|
||||
function Int(n)
|
||||
function Log(n)
|
||||
function Max(a, b)
|
||||
function Min(a, b)
|
||||
function OrBit(a, b)
|
||||
function Radians(d)
|
||||
function Randomize(n)
|
||||
function Rand(n)
|
||||
function Round(n)
|
||||
function Sign(n)
|
||||
function Sin(n)
|
||||
function Sqrt(n)
|
||||
function Tan(n)
|
||||
function XOrBit(a, b)
|
||||
'Strings
|
||||
function Asc(c$)
|
||||
function Chr$(n)
|
||||
function Insert$(src$, tgt$, pos)
|
||||
function InStr(src$, substr$)
|
||||
function LCase$(src$)
|
||||
function Left$(src$, n)
|
||||
function Length(src$)
|
||||
function Len(src$)
|
||||
function LTrim$(src$)
|
||||
function Mid$(src$, start, n)
|
||||
function ReplaceSubstr$(src$, rpc$, pos)
|
||||
function Replace$(src$, tgt$, rpc$)
|
||||
function Reverse$(src$)
|
||||
function Right$(src$, n)
|
||||
function RTrim$(src$)
|
||||
function StringFill$(src$, n)
|
||||
function Str$(n)
|
||||
function Str_F$(n)
|
||||
function Str_S$(n)
|
||||
function Tally(src$, substr$)
|
||||
function Trim$(src$)
|
||||
function UCase$(src$)
|
||||
function Val(n$)
|
||||
'Stacks
|
||||
sub Stack_N(n)
|
||||
sub Stack_S(n)
|
||||
sub Push_N(n)
|
||||
function Pop_N()
|
||||
sub Push_S(s$)
|
||||
function Pop_S$()
|
||||
function Stack_Size_N()
|
||||
function Stack_Size_S()
|
||||
'File I/O
|
||||
function FileOpen(stream, fileName$, mode)
|
||||
sub FileClose(stream)
|
||||
function ReadByte(stream)
|
||||
sub WriteByte(stream, byte)
|
||||
function ReadLine$(stream)
|
||||
sub Write(stream, txt$)
|
||||
sub WriteLine(stream, txt$)
|
||||
sub CopyFile(src$, dst$)
|
||||
function RemoveFile(fileName$)
|
||||
function FileExists(fileName$)
|
||||
function MoveFile(src$, dst$)
|
||||
function RenameFile(src$, dst$)
|
||||
function FileLength(fileName$)
|
||||
function Tell(stream)
|
||||
function Seek(stream, pos)
|
||||
function EOF(stream)
|
||||
function FreeFile()
|
||||
'Directories
|
||||
sub ChangeDir(p$)
|
||||
function DirExists(p$)
|
||||
function DirFirst$()
|
||||
function Dir$()
|
||||
function DirNext$()
|
||||
function MakeDir(p$)
|
||||
function RemoveDir(p$)
|
||||
'Date and Time
|
||||
function Date$()
|
||||
function Easter$(year)
|
||||
function Ticks()
|
||||
function Time$()
|
||||
function Timer()
|
||||
sub Wait(m_sec)
|
||||
'Window Management
|
||||
sub WindowOpen(win, title$, x, y, w, h, flag, vsync)
|
||||
sub WindowClose(win)
|
||||
sub RaiseWindow(win)
|
||||
sub Window(win)
|
||||
sub Update()
|
||||
sub Cls()
|
||||
sub SetClearColor(c)
|
||||
sub ShowWindow(win)
|
||||
sub HideWindow(win)
|
||||
sub SetWindowTitle(win, title$)
|
||||
function WindowTitle$(win)
|
||||
sub SetWindowPosition(win, x, y)
|
||||
sub GetWindowPosition(win, byref x, byref y)
|
||||
sub SetWindowSize(win, w, h)
|
||||
sub GetWindowSize(win, byref w, byref h)
|
||||
sub SetWindowMinSize(win, w, h)
|
||||
sub GetWindowMinSize(win, byref w, byref h)
|
||||
sub SetWindowMaxSize(win, w, h)
|
||||
sub GetWindowMaxSize(win, byref w, byref h)
|
||||
function WindowIsFullscreen(win)
|
||||
function WindowIsVisible(win)
|
||||
function WindowIsBordered(win)
|
||||
function WindowIsResizable(win)
|
||||
function WindowIsMinimized(win)
|
||||
function WindowIsMaximized(win)
|
||||
function WindowHasInputFocus(win)
|
||||
function WindowHasMouseFocus(win)
|
||||
sub SetWindowFullscreen(win, flag)
|
||||
sub MaximizeWindow(win)
|
||||
sub MinimizeWindow(win)
|
||||
sub SetWindowBorder(win, flag)
|
||||
sub WindowClip(slot, x, y, w, h)
|
||||
function WindowExists(win)
|
||||
function NumWindows()
|
||||
function WindowEvent_Close(win)
|
||||
function WindowEvent_Maximize(win)
|
||||
function WindowEvent_Minimize(win)
|
||||
function ActiveWindow()
|
||||
function FPS()
|
||||
sub SetWindowIcon(win, slot)
|
||||
'Canvases
|
||||
sub CanvasOpen(c_num, w, h, viewport_x, viewport_y, viewport_w, viewport_h, mode)
|
||||
sub CanvasClose(c_num)
|
||||
sub SetCanvasVisible(c_num, flag)
|
||||
function CanvasIsVisible(c_num)
|
||||
sub SetCanvasViewport(cnum, x, y, w, h)
|
||||
sub GetCanvasViewport(c_num, byref x, byref y, byref w, byref h)
|
||||
sub Canvas(c_num)
|
||||
sub SetCanvasOffset(c_num, x, y)
|
||||
sub GetCanvasOffset(c_num, byref x, byref y)
|
||||
sub GetCanvasSize(c_num, byref w, byref h)
|
||||
sub ClearCanvas()
|
||||
sub SetCanvasAlpha(c_num, a)
|
||||
function CanvasAlpha(c_num)
|
||||
function SetCanvasBlendMode(c_num, blend_mode)
|
||||
function CanvasBlendMode(c_num)
|
||||
function SetCanvasColorMod(c_num, c)
|
||||
function CanvasColorMod(c_num)
|
||||
sub CopyCanvas(src, x, y, w, h, dst, dx, dy)
|
||||
sub CloneCanvas(src, dst)
|
||||
sub SetCanvasZ(c_num, z)
|
||||
function CanvasZ(c_num)
|
||||
sub CanvasClip(slot, x, y, w, h, flag)
|
||||
function ActiveCanvas()
|
||||
'Graphics Primitives
|
||||
sub Box(x1, y1, x2, y2)
|
||||
sub BoxFill(x1, y1, x2, y2)
|
||||
sub Circle(x,y,radius)
|
||||
sub CircleFill(x,y,radius)
|
||||
sub Ellipse(x,y,rx,ry)
|
||||
sub EllipseFill(x,y,rx,ry)
|
||||
sub FloodFill(x,y)
|
||||
function GetPixel(x,y)
|
||||
sub SetColor(c)
|
||||
sub Line(x1, y1, x2, y2)
|
||||
sub Poly(n, byref x, byref y)
|
||||
sub PolyFill(n, byref x, byref y)
|
||||
sub Rect(x, y, w, h)
|
||||
sub RectFill(x, y, w, h)
|
||||
sub RoundRect(x, y, w, h, r)
|
||||
sub RoundRectFill(x, y, w, h, r)
|
||||
function RGB(r,g,b)
|
||||
function RGBA(r,g,b,a)
|
||||
sub PSet(x,y)
|
||||
'Images
|
||||
sub LoadImage(slot, img$)
|
||||
sub LoadImage_Ex(slot, img$, colkey)
|
||||
sub ImageFromBuffer(slot, w, h, byref buffer)
|
||||
sub ImageFromBuffer_Ex(slot, w, h, byref buffer, colkey)
|
||||
sub BufferFromImage(slot, byref buffer)
|
||||
function ImageExists(slot)
|
||||
sub ColorKey(slot, c)
|
||||
sub CopyImage(src, dst)
|
||||
sub DeleteImage(slot)
|
||||
sub SetImageAlpha(slot, a)
|
||||
function ImageAlpha(slot)
|
||||
sub GetImageSize(slot, byref w, byref h)
|
||||
function SetImageBlendMode(slot, blend_mode)
|
||||
function ImageBlendMode(slot)
|
||||
function SetImageColorMod(slot, c)
|
||||
function ImageColorMod(slot)
|
||||
sub DrawImage(slot, x, y)
|
||||
sub DrawImage_Blit(slot, x, y, src_x, src_y, src_w, src_h)
|
||||
sub DrawImage_Blit_Ex(slot, x, y, w, h, src_x, src_y, src_w, src_h)
|
||||
sub DrawImage_Rotate(slot, x, y, angle)
|
||||
sub DrawImage_Rotate_Ex(slot, x, y, src_x, src_y, src_w, src_h, angle)
|
||||
sub DrawImage_Zoom(slot, x, y, zx, zy)
|
||||
sub DrawImage_Zoom_Ex(slot, x, y, src_x, src_y, src_w, src_h, zx, zy)
|
||||
sub DrawImage_Rotozoom(slot, x, y, angle, zx, zy)
|
||||
sub DrawImage_Rotozoom_Ex(slot, x, y, src_x, src_y, src_w, src_h, angle, zx, zy)
|
||||
sub DrawImage_Flip(slot, x, y, h, v)
|
||||
sub DrawImage_Flip_Ex(slot, x, y, src_x, src_y, src_w, src_h, h, v)
|
||||
'Keyboard and Mouse
|
||||
function InKey()
|
||||
function Key(key_code)
|
||||
function WaitKey()
|
||||
sub HideMouse()
|
||||
sub ShowMouse()
|
||||
function MouseIsVisible()
|
||||
sub GetMouse(byref x, byref y, byref mb1, byref mb2, byref mb3)
|
||||
function MouseX()
|
||||
function MouseY()
|
||||
function MouseButton(mb)
|
||||
sub GetMouseWheel(byref x_axis, byref y_axis)
|
||||
function MouseWheelX()
|
||||
function MouseWheelY()
|
||||
'Sound and Music
|
||||
sub SoundFromBuffer(slot, byref buffer, buffer_size, vol)
|
||||
sub LoadSound(slot, snd_file$)
|
||||
sub LoadMusic(music_file$)
|
||||
sub PlaySound(slot, channel, loops)
|
||||
sub PlaySoundTimed(slot, channel, loops, ms)
|
||||
sub PlayMusic(mLoops)
|
||||
sub PauseSound(channel)
|
||||
sub ResumeSound(channel)
|
||||
sub PauseMusic()
|
||||
sub ResumeMusic()
|
||||
sub DeleteSound(slot)
|
||||
sub DeleteMusic()
|
||||
sub FadeMusicIn(fade_time, loops)
|
||||
sub FadeMusicOut(fade_time)
|
||||
function MusicExists()
|
||||
sub SetMusicVolume(vol)
|
||||
function MusicVolume()
|
||||
sub SetMusicPosition(pos)
|
||||
function MusicPosition()
|
||||
sub RewindMusic()
|
||||
sub SetSoundChannels(max_channels)
|
||||
function NumSoundChannels()
|
||||
function SoundIsEnabled()
|
||||
function SoundExists(slot)
|
||||
sub SetChannelVolume(channel, vol)
|
||||
function ChannelVolume(channel)
|
||||
sub SetSoundVolume(slot, vol)
|
||||
function SoundVolume(slot)
|
||||
sub StopMusic()
|
||||
sub StopSound(channel)
|
||||
function SetChannelPanning(channel, left_value, right_value)
|
||||
function SetChannelDistance(channel, dist_value)
|
||||
function ChannelIsPlaying(channel)
|
||||
function ChannelIsPaused(channel)
|
||||
'Joysticks
|
||||
function NumJoysticks()
|
||||
function NumJoyAxes(joy_num)
|
||||
function NumJoyButtons(joy_num)
|
||||
function NumJoyHats(joy_num)
|
||||
function NumJoyTrackBalls(joy_num)
|
||||
function JoyAxis(joy_num, joy_axis)
|
||||
function JoyButton(joy_num, joy_button)
|
||||
function JoyHat(joy_num, joy_hat)
|
||||
sub GetJoyTrackBall(joy_num, ball, byref dx, byref dy)
|
||||
function JoyName$(joy_num)
|
||||
function JoystickIsConnected(joy_num)
|
||||
'Screen Console
|
||||
sub GetCursor(byref x, byref y)
|
||||
sub PrintS(txt$)
|
||||
function InputS$(prompt$)
|
||||
function ZoneInputS$(x, y, w, h)
|
||||
sub Locate(x, y)
|
||||
'Text Editing
|
||||
sub ReadInput_Start()
|
||||
sub ReadInput_Stop()
|
||||
function ReadInput_Text$()
|
||||
sub ReadInput_SetText(txt$)
|
||||
sub ReadInput_ToggleBackspace(flag)
|
||||
'Text Drawing
|
||||
sub LoadFont(slot, fnt_file$, size)
|
||||
sub DeleteFont(slot)
|
||||
function FontIsLoaded(slot)
|
||||
sub Font(slot)
|
||||
sub SetFontStyle(slot, style)
|
||||
sub DrawText(txt$, x, y)
|
||||
sub DrawText_Shaded(txt$, x, y, fg_color, bg_color)
|
||||
sub DrawText_Blended(txt$, x, y)
|
||||
sub RenderText(slot, txt$)
|
||||
sub GetTextSize(slot, txt$, byref w, byref h)
|
||||
'Touch Events
|
||||
function TouchPressure()
|
||||
sub GetTouch(byref status, byref x, byref y, byref dx, byref dy)
|
||||
sub GetMultiTouch(byref status, byref x, byref y, byref fingers, byref dist, byref theta)
|
||||
sub GetTouchFinger(finger, byref x, byref y, byref pressure)
|
||||
function NumFingers()
|
||||
'Networking
|
||||
function CheckSockets(timeout_ms)
|
||||
function TCP_SocketReady(socket)
|
||||
function UDP_SocketReady(socket)
|
||||
function TCP_SocketOpen(socket, host$, port)
|
||||
sub TCP_SocketClose(socket)
|
||||
function TCP_RemoteHost(socket)
|
||||
function TCP_RemotePort(socket)
|
||||
function TCP_GetData(socket, ByRef sData$, numBytes)
|
||||
sub TCP_SendData(socket, sData$)
|
||||
function TCP_AcceptSocket(server, client)
|
||||
function UDP_SocketOpen(socket, port)
|
||||
function UDP_SocketClose(socket)
|
||||
function UDP_GetData(socket, byref sData$, byref host$, byref port)
|
||||
function UDP_Length()
|
||||
function UDP_MaxLength()
|
||||
function UDP_RemoteHost$(socket)
|
||||
function UDP_RemotePort(socket)
|
||||
sub UDP_SendData(socket, sData$, host$, port)
|
||||
'Video Playback
|
||||
sub LoadVideo(vid$)
|
||||
sub PlayVideo(vLoops)
|
||||
sub PauseVideo()
|
||||
sub StopVideo()
|
||||
sub SetVideoPosition(pos)
|
||||
sub ResumeVideo()
|
||||
function VideoPosition()
|
||||
sub DeleteVideo()
|
||||
function VideoIsPlaying()
|
||||
function VideoEnd()
|
||||
sub GetVideoStats(vFile$, byref vLen, byref vfps, byref frame_w, byref frame_h)
|
||||
sub SetVideoDrawRect(x, y, w, h)
|
||||
sub GetVideoDrawRect(byref x, byref y, byref w, byref h)
|
||||
sub GetVideoSize(byref w, byref h)
|
||||
function VideoExists()
|
||||
sub SetVideoAlpha(a)
|
||||
'Operating System
|
||||
function System(cmd$)
|
||||
function OS$()
|
||||
function Command$(arg)
|
||||
function NumCommands()
|
||||
function Env$(v$)
|
||||
sub SetEnv(var$, value$, overwrite)
|
||||
function PrefPath$(org_name$, app_name$)
|
||||
function Android_GetExternalStoragePath$()
|
||||
function Android_GetExternalStorageState()
|
||||
function Android_GetInternalStoragePath$()
|
||||
function Android_JNI_Message$(arg$)
|
||||
function Runtime_Utility_Message$(arg$)
|
||||
'Clipboard
|
||||
function ClipboardText$()
|
||||
sub SetClipboardText(txt$)
|
||||
function HasClipboardText()
|
||||
|
||||
'v3.12
|
||||
Sub GetDesktopDisplayMode(index, ByRef w, ByRef h, ByRef freq)
|
||||
Sub DrawImage_Transform(slot, x, y, w, h, src_x, src_y, src_w, src_h, angle, center_x, center_y, flip_h, flip_v)
|
||||
Sub GetPowerInfo(ByRef status, ByRef secs, ByRef pct)
|
||||
Function SystemRam()
|
||||
Function SetRenderScaleQuality(n)
|
||||
Function EvalJS$(js_code$) 'Only useable in Emscripten
|
||||
Function GetRenderScaleQuality()
|
||||
|
||||
'v3.14
|
||||
sub GetGlobalMouse(ByRef x, ByRef y, ByRef mb1, ByRef mb2, ByRef mb3)
|
||||
function GlobalMouseX()
|
||||
function GlobalMouseY()
|
||||
sub GetAccel(accel_num, ByRef x, ByRef y, ByRef z)
|
||||
function AccelName$(accel_num)
|
||||
function NumAccels()
|
||||
sub GetGyro(gyro_num, ByRef x, ByRef y, ByRef z)
|
||||
function GyroName$(gyro_num)
|
||||
function NumGyros()
|
||||
sub JoyRumblePlay(joy_num, strength, duration)
|
||||
sub JoyRumbleStop(joy_num)
|
||||
function JoystickIsHaptic(joy_num)
|
||||
function WriteByteBuffer(stream, ByRef buf, buf_size)
|
||||
function ReadByteBuffer(stream, ByRef buf, buf_size)
|
||||
function WindowEvent_Resize(win)
|
||||
sub SetWindowAutoClose( win, exit_on_close )
|
||||
sub SetWindowResizable(win, flag) 'new
|
||||
function SystemReturnStdOut$(cmd$) 'new
|
||||
function WindowMode(visible, fullscreen, resizable, borderless, highDPI)
|
||||
function WindowFlags(win)
|
||||
sub RestoreWindow(win)
|
||||
sub UpdateAllWindows() 'new
|
||||
function QueryAudioSpec(ByRef freq, ByRef format, ByRef channels) 'new
|
||||
|
||||
'v3.15
|
||||
function MusicIsPlaying()
|
||||
|
||||
'v3.19
|
||||
function DrawGeometry(slot, num_vertices, ByRef vertices, num_indices, ByRef Indices)
|
||||
|
||||
'v3.20
|
||||
function Size(s$)
|
||||
function BufferFromString(s$, ByRef buffer)
|
||||
function StringFromBuffer$(ByRef buffer, buffer_size)
|
||||
sub GrabInput(flag)
|
||||
function GrabbedWindow()
|
||||
sub WarpMouse(x, y)
|
||||
sub WarpMouseGlobal(x, y)
|
||||
sub SetMouseZone(x, y, w, h)
|
||||
sub ClearMouseZone()
|
||||
sub SetWindowAlwaysOnTop(win, flag)
|
||||
sub SetMouseRelative(flag)
|
||||
sub SetWindowVSync(win, flag)
|
||||
function OpenURL(url$)
|
||||
function APIVersion$()
|
||||
function FlashWindow(win)
|
||||
function MessageBox(title$, msg$)
|
||||
sub NumberArrayCopy(ByRef src, ByRef dst)
|
||||
sub StringArrayCopy(ByRef src$, ByRef dst$)
|
||||
sub ArrayCopy(ByRef src, ByRef dst)
|
||||
sub NumberArrayFill(ByRef src, fdata)
|
||||
sub StringArrayFill(ByRef src$, fdata$)
|
||||
sub ArrayFill(ByRef src, fdata)
|
||||
function Runtime$()
|
||||
|
||||
'More v3.20 (Matrices and Parrallism)
|
||||
sub DimMatrix(m, m_rows, m_cols, preserve_flag)
|
||||
function AddMatrix(mA, mB, mC)
|
||||
function AugmentMatrix (mA, mB, mC)
|
||||
sub CopyMatrix(mA, mB)
|
||||
function InsertMatrixColumns(mA, c, num_cols)
|
||||
function InsertMatrixRows(mA, r, num_rows)
|
||||
function MultiplyMatrix (mA, mB, mC)
|
||||
function CubeMatrix(mA, mB)
|
||||
function DeleteMatrixColumns(mA, c, num_cols)
|
||||
function DeleteMatrixRows(mA, r, num_rows)
|
||||
sub ClearMatrix(mA)
|
||||
function ClearMatrixColumns (mA, c, num_cols)
|
||||
function ClearMatrixRows(mA, r, num_rows)
|
||||
sub FillMatrix(mA, v)
|
||||
function FillMatrixColumns(mA, c, num_cols, v)
|
||||
function FillMatrixRows(mA, r, num_rows, v)
|
||||
function CopyMatrixColumns(mA, mB, c, num_cols)
|
||||
function CopyMatrixRows (mA, mB, r, num_rows)
|
||||
sub IdentityMatrix(mA, n)
|
||||
function SolveMatrix(mA, mB, mC)
|
||||
function IsEqualMatrix(mA, mB, tolerance)
|
||||
function Determinant(mA)
|
||||
function AdjointMatrix(mA, mB)
|
||||
function InvertMatrix(mA, mB)
|
||||
sub MatrixFromBuffer(mA, r, c, ByRef buffer)
|
||||
sub GetMatrix(ByRef buffer, mA)
|
||||
sub RandomizeMatrix(mA, vmin, vmax)
|
||||
function MatrixValue(mA, r, c)
|
||||
sub SetMatrixValue(mA, r, c, v)
|
||||
sub ScalarMatrix (mA, mB, s_value)
|
||||
function ScalarMatrixColumns(mA, mB, c, num_cols, s_value)
|
||||
function ScalarMatrixRows(mA, mB, r, num_rows, s_value)
|
||||
function SquareMatrix(mA, mB)
|
||||
sub SubMatrix(mA, r, c)
|
||||
function SubtractMatrix (mA, mB, mC)
|
||||
sub SwapMatrix(mA, mB)
|
||||
function SwapMatrixColumn(mA, C1, C2)
|
||||
function SwapMatrixRow(mA, R1, R2)
|
||||
function TransposeMatrix(mA, mB)
|
||||
function UnAugmentMatrix(mA, mB, mC)
|
||||
sub ZeroMatrix(mA)
|
||||
|
||||
sub GetMatrixSize(mA, ByRef r, ByRef c)
|
||||
function SetMatrixProcess(p_num) 'Set to -1 for main thread
|
||||
|
||||
|
||||
'ERROR_FLAG - MATRIX_ON_ERROR_STOP, MATRIX_ON_ERROR_WAIT, MATRIX_ON_ERROR_CONTINUE
|
||||
function ProcessOpen(p_num) 'stops and locks mutex, and clears queue before changing mode
|
||||
sub SetProcessErrorMode(p_num, error_mode)
|
||||
function ProcessError(p_num)
|
||||
sub ProcessWait(p_num) 'waits for all calculations to complete and lock matrix mutex
|
||||
sub ProcessWaitAll() 'waits for all process to finish
|
||||
sub ProcessContinue(p_num) 'unlock mutex
|
||||
sub ProcessStop(p_num) 'stops after current calculation its working on and lock mutex
|
||||
sub ProcessClear(p_num) 'locks mutex and clears matrix queue
|
||||
function ProcessClose(p_num)
|
||||
function ProcessErrorMode(p_num)
|
||||
sub ProcessSleep(p_num, msec)
|
||||
function ProcessExists(p_num)
|
||||
sub ProcessStopAll()
|
||||
sub ProcessContinueAll()
|
||||
function ProcessQueueSize(p_num)
|
||||
|
||||
function NumCPUs()
|
||||
|
||||
'v3.21
|
||||
sub GetProjectionGeometry(cam_dist, mA, f_vertex_count, ByRef columns, ByRef uv, graph_offset_x, graph_offset_y, v_color, ByRef vertex_count, ByRef vertex2D, ByRef index_count, ByRef index, ByRef clip_dist, ByRef min_x, ByRef min_y, ByRef max_x, ByRef max_y)
|
||||
function CalculateFaceZ(cam_dist, graph_offset_x, graph_offset_y, view_w, view_h, view_depth, mA, f_vertex_count, ByRef columns, ByRef face_min_z, ByRef face_max_z, ByRef z_avg)
|
||||
function SetChannelSpacePosition(channel, angle, distance)
|
||||
function SaveBMP(img, file$)
|
||||
function SavePNG(img, file$)
|
||||
function SaveJPG(img, file$)
|
||||
Function GetLineIntersection(p0_x, p0_y, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y, ByRef i_x, ByRef i_y)
|
||||
Function Interpolate(min_a, max_a, mid_a, min_b, max_b)
|
||||
Function ATan2(y, x)
|
||||
function PointInQuad(x, y, x1, y1, x2, y2, x3, y3, x4, y4)
|
||||
function PointInTri(x, y, x1, y1, x2, y2, x3, y3)
|
||||
Function Distance2D(x1, y1, x2, y2)
|
||||
Function Distance3D(x1, y1, z1, x2, y2, z2)
|
||||
function GetCircleLineIntersection(circle_x, circle_y, radius, x1, y1, x2, y2, ByRef ix1, ByRef iy1, ByRef ix2, ByRef iy2)
|
||||
function GetLinePlaneIntersection(ByRef line_point, ByRef line_direction, ByRef plane_point_1, ByRef plane_point_2, ByRef plane_point_3, ByRef intersection)
|
||||
sub IncrementMatrixRows(mA, mB, r, num_rows, value)
|
||||
sub IncrementMatrixColumns(mA, mB, c, num_cols, value)
|
||||
sub JoinMatrixRows(mA, mB, mC)
|
||||
sub JoinMatrixColumns(mA, mB, mC)
|
||||
64
rcbasic_build/env_resolve.h
Normal file
64
rcbasic_build/env_resolve.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef ENV_RESOLVE_H_INCLUDED
|
||||
#define ENV_RESOLVE_H_INCLUDED
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
|
||||
#define RC_WINDOWS
|
||||
#elif __APPLE__
|
||||
#define RC_MAC
|
||||
#elif __linux__
|
||||
#define RC_LINUX
|
||||
#endif
|
||||
|
||||
#ifdef RC_WINDOWS
|
||||
#include <winbase.h>
|
||||
#else
|
||||
#include <cstdlib>
|
||||
#endif // RC_WINDOWS
|
||||
|
||||
string rc_intern_env(string v)
|
||||
{
|
||||
#ifdef RC_WINDOWS
|
||||
char * val = new char[32767];
|
||||
int n = GetEnvironmentVariable(v.c_str(), val, 32767);
|
||||
string rtn = "";
|
||||
if (n>0)
|
||||
rtn = (string)val;
|
||||
delete val;
|
||||
return rtn;
|
||||
#else
|
||||
char * c = getenv(v.c_str());
|
||||
if(c != NULL)
|
||||
return (string) c;
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
string resolveEnvironmentVariables(string sdata)
|
||||
{
|
||||
string sdata_out = "";
|
||||
for(int i = 0; i < sdata.length(); i++)
|
||||
{
|
||||
if(sdata.substr(i, 2).compare("${")==0)
|
||||
{
|
||||
int end_index = sdata.substr(i+2).find_first_of("}");
|
||||
if(end_index == string::npos)
|
||||
{
|
||||
cout << "Error: Missing closing } in environment variable" << endl;
|
||||
return sdata_out;
|
||||
}
|
||||
string env_var = sdata.substr(i+2).substr(0, end_index);
|
||||
//cout << "env_var is " << env_var << endl;
|
||||
string env_value = rc_intern_env(env_var);
|
||||
sdata_out += env_value;
|
||||
i = (i+2) + end_index;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
sdata_out += sdata.substr(i, 1);
|
||||
}
|
||||
}
|
||||
return sdata_out;
|
||||
}
|
||||
|
||||
#endif // ENV_RESOLVE_H_INCLUDED
|
||||
231
rcbasic_build/file_directory.h
Normal file
231
rcbasic_build/file_directory.h
Normal file
@@ -0,0 +1,231 @@
|
||||
#ifndef FILE_DIRECTORY_H_INCLUDED
|
||||
#define FILE_DIRECTORY_H_INCLUDED
|
||||
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
|
||||
#define RC_WINDOWS
|
||||
#elif __APPLE__
|
||||
#define RC_MAC
|
||||
#elif __linux__
|
||||
#define RC_LINUX
|
||||
#endif
|
||||
|
||||
|
||||
#include <sys/stat.h> //file system stuff
|
||||
#include <sys/types.h> //file system stuff
|
||||
#include <unistd.h> //file system stuff
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#ifdef RC_MAC
|
||||
#define RC_GETCWD
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#ifdef RC_WINDOWS
|
||||
#include <tchar.h>
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
#endif // RC_WINDOWS
|
||||
|
||||
|
||||
#ifndef RC_WINDOWS
|
||||
|
||||
struct dirent *rc_entry;
|
||||
DIR *rc_dir;
|
||||
string rc_dir_path = "";
|
||||
|
||||
#else
|
||||
|
||||
struct dirent *rc_entry;
|
||||
string rc_dir;
|
||||
string rc_dir_path = "";
|
||||
HANDLE hfind;
|
||||
|
||||
#endif // RC_LINUX
|
||||
|
||||
|
||||
#ifndef RC_WINDOWS
|
||||
|
||||
|
||||
#ifdef RC_LINUX
|
||||
inline int rc_intern_dirChange(string ch_path)
|
||||
{
|
||||
if(chdir(ch_path.c_str())!=0)
|
||||
{
|
||||
cout << "Error: Could not change directory\n";
|
||||
return 2;
|
||||
}
|
||||
rc_dir_path = get_current_dir_name();
|
||||
return 0;
|
||||
}
|
||||
#endif // RC_LINUX
|
||||
|
||||
inline bool rc_intern_dirExist(string d_path)
|
||||
{
|
||||
struct stat info;
|
||||
|
||||
if(stat( d_path.c_str(), &info ) != 0)
|
||||
return false;
|
||||
else if(info.st_mode & S_IFDIR)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef RC_GETCWD
|
||||
string getcwd_str()
|
||||
{
|
||||
char *buffer = new char[MAXPATHLEN];
|
||||
getcwd(buffer,MAXPATHLEN);
|
||||
if(buffer != NULL)
|
||||
{
|
||||
string ret(buffer);
|
||||
delete[] buffer;
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
return string();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline int rc_intern_dirChange(string ch_path)
|
||||
{
|
||||
if(chdir(ch_path.c_str())!=0)
|
||||
{
|
||||
cout << "Error: Could not change directory\n";
|
||||
return 2;
|
||||
}
|
||||
rc_dir_path = getcwd_str();
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline string rc_intern_dir()
|
||||
{
|
||||
string d = getcwd_str();
|
||||
//__android_log_print(ANDROID_LOG_ERROR, "RC_DEBUG_DIR", "%s", SDL_GetPrefPath("rcbasic","lucky"));
|
||||
if(d.compare("")==0)
|
||||
{
|
||||
//cout << "Could not get current directory" << endl;
|
||||
return "";
|
||||
}
|
||||
rc_dir_path = d;
|
||||
return d;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline string rc_intern_dir()
|
||||
{
|
||||
string d = get_current_dir_name();
|
||||
if(d.compare("")==0)
|
||||
{
|
||||
cout << "Could not get current directory" << endl;
|
||||
return "";
|
||||
}
|
||||
rc_dir_path = d;
|
||||
return d;
|
||||
}
|
||||
|
||||
#endif // RC_ANDROID
|
||||
|
||||
|
||||
#else
|
||||
|
||||
inline int rc_intern_dirChange(string dpath)
|
||||
{
|
||||
if(SetCurrentDirectory(dpath.c_str())==0)
|
||||
{
|
||||
cout << "Error: Could not change directory\n";
|
||||
return 2;
|
||||
}
|
||||
|
||||
DWORD nBufferLength = MAX_PATH;
|
||||
char szCurrentDirectory[MAX_PATH + 1];
|
||||
GetCurrentDirectory(nBufferLength, szCurrentDirectory);
|
||||
szCurrentDirectory[MAX_PATH] = '\0';
|
||||
|
||||
rc_dir_path = (string)szCurrentDirectory;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool dirExists(const std::string& dirName_in)
|
||||
{
|
||||
DWORD ftyp = GetFileAttributesA(dirName_in.c_str());
|
||||
if (ftyp == INVALID_FILE_ATTRIBUTES)
|
||||
return false; //something is wrong with your path!
|
||||
|
||||
if (ftyp & FILE_ATTRIBUTE_DIRECTORY)
|
||||
return true; // this is a directory!
|
||||
|
||||
return false; // this is not a directory!
|
||||
}
|
||||
|
||||
inline int rc_intern_dirExist(string dpath)
|
||||
{
|
||||
return dirExists(dpath);
|
||||
}
|
||||
|
||||
HANDLE hFind;
|
||||
WIN32_FIND_DATA ffd;
|
||||
|
||||
inline string rc_intern_dir()
|
||||
{
|
||||
TCHAR buf[MAX_PATH];
|
||||
GetCurrentDirectory(MAX_PATH, buf);
|
||||
string d = buf;
|
||||
|
||||
if(d.compare("")==0)
|
||||
{
|
||||
cout << "Could not get current directory" << endl;
|
||||
return "";
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
#endif // RC_WINDOWS
|
||||
|
||||
|
||||
string rc_absFilePath(string file_path)
|
||||
{
|
||||
//cout << "file_path: " << file_path << endl;
|
||||
string cwd = rc_intern_dir();
|
||||
int start_index = 0;
|
||||
string::size_type bs_index = file_path.find_last_of("\\");
|
||||
string::size_type fs_index = file_path.find_last_of("/");
|
||||
int end_index = 0;
|
||||
|
||||
if(bs_index==string::npos && fs_index==string::npos)
|
||||
{
|
||||
#ifdef RC_WINDOWS
|
||||
return cwd + "\\" + file_path;
|
||||
#else
|
||||
return cwd + "/" + file_path;
|
||||
#endif // RC_WINDOWS
|
||||
}
|
||||
|
||||
end_index = ( (bs_index > fs_index || fs_index == string::npos) && bs_index != string::npos) ? bs_index : fs_index;
|
||||
|
||||
|
||||
if(rc_intern_dirExist(file_path.substr(0, end_index)))
|
||||
{
|
||||
rc_intern_dirChange(file_path.substr(0, end_index));
|
||||
|
||||
#ifdef RC_WINDOWS
|
||||
string abs_file_path = rc_intern_dir() + "\\" + file_path.substr(end_index+1);
|
||||
#else
|
||||
string abs_file_path = rc_intern_dir() + "/" + file_path.substr(end_index+1);
|
||||
#endif // RC_WINDOWS
|
||||
|
||||
rc_intern_dirChange(cwd);
|
||||
return abs_file_path;
|
||||
}
|
||||
|
||||
return file_path;
|
||||
}
|
||||
|
||||
|
||||
#endif // FILE_DIRECTORY_H_INCLUDED
|
||||
1248
rcbasic_build/identifier.h
Normal file
1248
rcbasic_build/identifier.h
Normal file
File diff suppressed because it is too large
Load Diff
48
rcbasic_build/keywords.h
Normal file
48
rcbasic_build/keywords.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef KEYWORDS_H_INCLUDED
|
||||
#define KEYWORDS_H_INCLUDED
|
||||
|
||||
using namespace std;
|
||||
|
||||
string keyWords[] = {
|
||||
"AND", //1
|
||||
"OR", //2
|
||||
"XOR", //3
|
||||
"EXIT", //4
|
||||
"MOD", //5
|
||||
"SHL", //6
|
||||
"SHR", //7
|
||||
"FUNCTION", //8
|
||||
"RETURN", //9
|
||||
"DIM", //10
|
||||
"END", //11
|
||||
"FOR", //12
|
||||
"TO", //13
|
||||
"STEP", //14
|
||||
"NEXT", //15
|
||||
"WHILE", //16
|
||||
"WEND", //17
|
||||
"DO", //18
|
||||
"LOOP", //19
|
||||
"UNTIL", //20
|
||||
"SELECT", //21
|
||||
"CASE", //22
|
||||
"DEFAULT", //23
|
||||
"IF", //24
|
||||
"ELSE", //25
|
||||
"THEN", //26
|
||||
"DELETE", //27
|
||||
"INCLUDE", //30
|
||||
"BYREF", //31
|
||||
"PRINT", //32
|
||||
"SUB", //33
|
||||
"NOT", //34
|
||||
"ELSEIF", //35
|
||||
"REDIM", //, //36
|
||||
"CONST", //37
|
||||
"ONCE", //38
|
||||
"CONTINUE", //39
|
||||
"AS", //40
|
||||
"TYPE" //41
|
||||
};
|
||||
|
||||
#endif // KEYWORDS_H_INCLUDED
|
||||
1173
rcbasic_build/main.cpp
Normal file
1173
rcbasic_build/main.cpp
Normal file
File diff suppressed because it is too large
Load Diff
6079
rcbasic_build/parser.h
Normal file
6079
rcbasic_build/parser.h
Normal file
File diff suppressed because it is too large
Load Diff
1428
rcbasic_build/rc_builtin.h
Normal file
1428
rcbasic_build/rc_builtin.h
Normal file
File diff suppressed because it is too large
Load Diff
20
rcbasic_build/rc_debug.h
Normal file
20
rcbasic_build/rc_debug.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef RC_DEBUG_H_INCLUDED
|
||||
#define RC_DEBUG_H_INCLUDED
|
||||
|
||||
using namespace std;
|
||||
|
||||
string ERROR_MSG = "";
|
||||
|
||||
void rc_setError(string rc_error)
|
||||
{
|
||||
ERROR_MSG += rc_error + "\n";
|
||||
}
|
||||
|
||||
string rc_getError()
|
||||
{
|
||||
string error_out = ERROR_MSG;
|
||||
//ERROR_MSG = "";
|
||||
return error_out;
|
||||
}
|
||||
|
||||
#endif // RC_DEBUG_H_INCLUDED
|
||||
213
rcbasic_build/rc_global.h
Normal file
213
rcbasic_build/rc_global.h
Normal file
@@ -0,0 +1,213 @@
|
||||
#ifndef RC_GLOBAL_INCLUDED
|
||||
#define RC_GLOBAL_INCLUDED
|
||||
#include <inttypes.h>
|
||||
|
||||
#define CODE_SEGMENT 0
|
||||
#define DATA_SEGMENT 1
|
||||
|
||||
struct rc_label
|
||||
{
|
||||
string label_name="";
|
||||
uint64_t label_address=0;
|
||||
int label_segment = 0;
|
||||
};
|
||||
|
||||
class rc_vm_asm
|
||||
{
|
||||
public:
|
||||
vector<string> vm_code;
|
||||
vector<rc_label> label;
|
||||
int current_segment = 0;
|
||||
uint64_t current_address[2];
|
||||
uint64_t n_stack_count = 0;
|
||||
uint64_t s_stack_count = 0;
|
||||
uint64_t u_stack_count = 0;
|
||||
uint64_t max_n_stack_count = 0;
|
||||
uint64_t max_s_stack_count = 0;
|
||||
uint64_t max_u_stack_count = 0;
|
||||
|
||||
void push_back(string s)
|
||||
{
|
||||
s += " ";
|
||||
vm_code.push_back(s);
|
||||
if(s.substr(0,s.find_first_of(" ")).compare(".code")==0)
|
||||
{
|
||||
current_segment = CODE_SEGMENT;
|
||||
}
|
||||
else if(s.substr(0,s.find_first_of(" ")).compare(".data")==0)
|
||||
{
|
||||
//cout << "got data son" << endl;
|
||||
current_segment = DATA_SEGMENT;
|
||||
}
|
||||
else if(s.substr(0,s.find_first_of(" ")).compare("label")==0)
|
||||
{
|
||||
rc_label current_label;
|
||||
s = s.substr(s.find_first_of(" "));
|
||||
s = s.substr(s.find_first_not_of(" "));
|
||||
current_label.label_name = s;
|
||||
current_label.label_address = current_address[current_segment];
|
||||
current_label.label_segment = current_segment;
|
||||
//cout << "got a mutha flippin label: " << current_label.label_name << " : " << current_label.label_segment << endl;
|
||||
label.push_back(current_label);
|
||||
}
|
||||
else if(s.substr(0,s.find_first_of(" ")).compare("mov")==0 || s.substr(0,s.find_first_of(" ")).compare("mov$")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("mov_r")==0 || s.substr(0,s.find_first_of(" ")).compare("mov_r$")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("mov_type")==0 || s.substr(0,s.find_first_of(" ")).compare("add$")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("add")==0 || s.substr(0,s.find_first_of(" ")).compare("sub")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("mul")==0 || s.substr(0,s.find_first_of(" ")).compare("div")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("pow")==0 || s.substr(0,s.find_first_of(" ")).compare("mod")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("shl")==0 || s.substr(0,s.find_first_of(" ")).compare("shr")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("and")==0 || s.substr(0,s.find_first_of(" ")).compare("or")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("xor")==0 || s.substr(0,s.find_first_of(" ")).compare("mov_arr$")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("cmp")==0 || s.substr(0,s.find_first_of(" ")).compare("cmp$")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("cmp_u")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_num1")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("obj_str1")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr1")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("dim_type")==0 || s.substr(0,s.find_first_of(" ")).compare("dim_num1")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("dim_str1")==0 || s.substr(0,s.find_first_of(" ")).compare("loop_while")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("loop_until")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("while")==0 || s.substr(0,s.find_first_of(" ")).compare("mov_arr")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("ptr")==0 || s.substr(0,s.find_first_of(" ")).compare("ptr$")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("redim1")==0 || s.substr(0,s.find_first_of(" ")).compare("redim1$")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("for_offset_arr2")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_n1")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("obj_usr_s1")==0 || s.substr(0,s.find_first_of(" ")).compare("uref_ptr")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("obj_usr_init1")==0 || s.substr(0,s.find_first_of(" ")).compare("preset_t")==0)
|
||||
{
|
||||
current_address[current_segment] += 17; //1 byte for instruction and 8 bytes for each argument
|
||||
}
|
||||
else if(s.substr(0,s.find_first_of(" ")).compare("push")==0 )
|
||||
{
|
||||
n_stack_count++;
|
||||
if( (n_stack_count+1) > max_n_stack_count)
|
||||
max_n_stack_count = n_stack_count+1;
|
||||
current_address[current_segment] += 9;
|
||||
}
|
||||
else if(s.substr(0,s.find_first_of(" ")).compare("push$")==0 )
|
||||
{
|
||||
s_stack_count++;
|
||||
if( (s_stack_count+1) > max_s_stack_count)
|
||||
max_s_stack_count = s_stack_count+1;
|
||||
current_address[current_segment] += 9;
|
||||
}
|
||||
else if(s.substr(0,s.find_first_of(" ")).compare("push_t")==0 )
|
||||
{
|
||||
u_stack_count++;
|
||||
if( (u_stack_count+1) > max_u_stack_count)
|
||||
max_u_stack_count = u_stack_count+1;
|
||||
current_address[current_segment] += 9;
|
||||
}
|
||||
else if(s.substr(0,s.find_first_of(" ")).compare("pop")==0)
|
||||
{
|
||||
n_stack_count--;
|
||||
current_address[current_segment] += 9;
|
||||
}
|
||||
else if(s.substr(0,s.find_first_of(" ")).compare("pop$")==0)
|
||||
{
|
||||
s_stack_count--;
|
||||
current_address[current_segment] += 9;
|
||||
}
|
||||
else if(s.substr(0,s.find_first_of(" ")).compare("pop_t")==0)
|
||||
{
|
||||
u_stack_count--;
|
||||
current_address[current_segment] += 9;
|
||||
}
|
||||
else if(s.substr(0,s.find_first_of(" ")).compare("jmp")==0 || s.substr(0,s.find_first_of(" ")).compare("je")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("jne")==0 || s.substr(0,s.find_first_of(" ")).compare("jg")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("jge")==0 || s.substr(0,s.find_first_of(" ")).compare("jl")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("jle")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_num")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("obj_str")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("obj_get")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_get$")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("obj_set")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_set$")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("delete")==0 || s.substr(0,s.find_first_of(" ")).compare("delete$")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("get_stack_size")==0 || s.substr(0,s.find_first_of(" ")).compare("get_stack_size$")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("wend")==0 || s.substr(0,s.find_first_of(" ")).compare("loop")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("gosub")==0 || s.substr(0,s.find_first_of(" ")).compare("print")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("print$")==0 || s.substr(0,s.find_first_of(" ")).compare("func")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("not")==0 || s.substr(0,s.find_first_of(" ")).compare("next")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("pop_ptr")==0 || s.substr(0,s.find_first_of(" ")).compare("preset")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("preset$")==0 || s.substr(0,s.find_first_of(" ")).compare("for_offset_arr1")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("end_x")==0 || s.substr(0,s.find_first_of(" ")).compare("lval")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("lval$")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_n")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("obj_usr_s")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_get")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("delete_t")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_init")==0)
|
||||
{
|
||||
current_address[current_segment] += 9; //1 byte for instruction and 8 bytes a single argument
|
||||
}
|
||||
else if(s.substr(0,s.find_first_of(" ")).compare("obj_num2")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_str2")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("obj_usr2")==0 || s.substr(0,s.find_first_of(" ")).compare("dim_type1")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("dim_num2")==0 || s.substr(0,s.find_first_of(" ")).compare("dim_str2")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("redim2")==0 || s.substr(0,s.find_first_of(" ")).compare("redim2$")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("for_offset_arr3")==0 || s.substr(0,s.find_first_of(" ")).compare("dbg")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("obj_usr_n2")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_s2")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("obj_usr_init2")==0 || s.substr(0,s.find_first_of(" ")).compare("preset_t1")==0)
|
||||
{
|
||||
current_address[current_segment] += 25; //1 byte for instruction and 8 bytes for 3 arguments
|
||||
}
|
||||
else if(s.substr(0,s.find_first_of(" ")).compare("dim_type2")==0 || s.substr(0,s.find_first_of(" ")).compare("dim_num3")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("dim_str3")==0 || s.substr(0,s.find_first_of(" ")).compare("for")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("obj_num3")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_str3")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("redim3")==0 || s.substr(0,s.find_first_of(" ")).compare("redim3$")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("obj_usr_n3")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_s3")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("obj_usr3")==0 || s.substr(0,s.find_first_of(" ")).compare("obj_usr_init3")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("preset_t2")==0)
|
||||
{
|
||||
current_address[current_segment] += 33; //1 byte for instruction and 8 bytes for 4 arguments
|
||||
}
|
||||
else if(s.substr(0,s.find_first_of(" ")).compare("dim_type3")==0 || s.substr(0,s.find_first_of(" ")).compare("preset_t3")==0)
|
||||
{
|
||||
current_address[current_segment] += 41; //1 byte for instruction and 8 bytes for 5 arguments
|
||||
}
|
||||
else if(s.substr(0,s.find_first_of(" ")).compare("end")==0 || s.substr(0,s.find_first_of(" ")).compare("clear_obj")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("push_empty$")==0 || s.substr(0,s.find_first_of(" ")).compare("clear_stack")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("clear_stack$")==0 || s.substr(0,s.find_first_of(" ")).compare("do")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("pop_loop_stack")==0 || s.substr(0,s.find_first_of(" ")).compare("return")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("println")==0 || s.substr(0,s.find_first_of(" ")).compare("for_offset_0")==0 ||
|
||||
s.substr(0,s.find_first_of(" ")).compare("push_t_null")==0)
|
||||
{
|
||||
current_address[current_segment] += 1; //1 byte for instruction and no arguments
|
||||
}
|
||||
else if(s.substr(0,s.find_first_of(" ")).compare("dim_tfield")==0)
|
||||
{
|
||||
current_address[current_segment] += 57;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Unknown Instruction" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
vm_code.clear();
|
||||
}
|
||||
|
||||
uint64_t size()
|
||||
{
|
||||
return vm_code.size();
|
||||
}
|
||||
};
|
||||
|
||||
rc_vm_asm vm_asm;
|
||||
|
||||
//vector<string> vm_asm; //the generated opcodes for the current set of
|
||||
//vector<string> vm_data_asm;
|
||||
|
||||
vector<unsigned char> data_segment;
|
||||
vector<string> resolveID_id_reg;
|
||||
vector<int> resolveID_id_type;
|
||||
vector<int> resolveID_id_ut_index;
|
||||
vector<uint32_t> resolveID_id_vec_pos;
|
||||
|
||||
int getResolveReg(string arg)
|
||||
{
|
||||
for(int i = 0; i < resolveID_id_reg.size(); i++)
|
||||
{
|
||||
//cout << "compare (" << arg << " to " << resolveID_id_reg[i] << endl;
|
||||
if(resolveID_id_reg[i].compare(arg)==0)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rid_count = 0;
|
||||
|
||||
#endif // RC_GLOBAL_INCLUDED
|
||||
72
rcbasic_build/rc_utility.h
Normal file
72
rcbasic_build/rc_utility.h
Normal file
@@ -0,0 +1,72 @@
|
||||
#ifndef RC_UTILITY_H_INCLUDED
|
||||
#define RC_UTILITY_H_INCLUDED
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <ctype.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
string rc_intToString(int a)
|
||||
{
|
||||
stringstream ss;
|
||||
ss << a;
|
||||
string str = ss.str();
|
||||
ss.clear();
|
||||
return str;
|
||||
}
|
||||
|
||||
string rc_uint64ToString(uint64_t a)
|
||||
{
|
||||
stringstream ss;
|
||||
ss << a;
|
||||
string str = ss.str();
|
||||
ss.clear();
|
||||
return str;
|
||||
}
|
||||
|
||||
int rc_stringToInt(string a)
|
||||
{
|
||||
stringstream ss;
|
||||
ss << a;
|
||||
int i = 0;
|
||||
ss >> i;
|
||||
ss.clear();
|
||||
return i;
|
||||
}
|
||||
|
||||
string StringToUpper(string strToConvert)
|
||||
{//change each element of the string to upper case
|
||||
for(unsigned int i=0;i<strToConvert.length();i++)
|
||||
{
|
||||
strToConvert[i] = toupper(strToConvert[i]);
|
||||
}
|
||||
return strToConvert;//return the converted string
|
||||
}
|
||||
|
||||
string StringToLower(string strToConvert)
|
||||
{//change each element of the string to lower case
|
||||
for(unsigned int i=0;i<strToConvert.length();i++)
|
||||
{
|
||||
strToConvert[i] = tolower(strToConvert[i]);
|
||||
}
|
||||
return strToConvert;//return the converted string
|
||||
}
|
||||
|
||||
string rc_substr(string s, int start_pos=0, int num_char=0)
|
||||
{
|
||||
if(start_pos < 0)
|
||||
return "";
|
||||
if(start_pos >= s.length())
|
||||
return "";
|
||||
if( (start_pos+num_char) >= s.length())
|
||||
return s.substr(start_pos);
|
||||
return s.substr(start_pos, num_char);
|
||||
}
|
||||
|
||||
bool is_file_exist(const char *fileName)
|
||||
{
|
||||
std::ifstream infile(fileName);
|
||||
return infile.good();
|
||||
}
|
||||
|
||||
#endif // RC_UTILITY_H_INCLUDED
|
||||
1480
rcbasic_build/rc_vm_asm.h
Normal file
1480
rcbasic_build/rc_vm_asm.h
Normal file
File diff suppressed because it is too large
Load Diff
1052
rcbasic_build/tokenizer.h
Normal file
1052
rcbasic_build/tokenizer.h
Normal file
File diff suppressed because it is too large
Load Diff
285
rcbasic_build/vm_asm
Normal file
285
rcbasic_build/vm_asm
Normal file
@@ -0,0 +1,285 @@
|
||||
-------------------------
|
||||
|types of parameters
|
||||
-------------------------
|
||||
raw_number = starting character (0-9)
|
||||
n# = starting character n followed by # (# is a number denoting the number register to use)
|
||||
s# = starting character s followed by # (# is a number denoting the string register to use)
|
||||
u# = starting character u followed by # (# is a number denoting the user_type register to use)
|
||||
r# = starting character r followed by # (# is a number denoting the reference register to use) //references are set when obj_get or mov(34) or mov(38) is called
|
||||
!id = starting character is ! followed id (id is a number denoting the id vector position) //it can be used for any integer argument as well as id's
|
||||
@[data_address] = starting character is @ followed by the number specifying the offset in the data segment
|
||||
|
||||
----------------------------------------
|
||||
|SYSTEM AND VM OPERATION
|
||||
---------------------------------------
|
||||
|
||||
0 - end
|
||||
1 - dbg uint uint uint // arguments are (debug_function, file_index, line_number)
|
||||
|
||||
---------------------------------------
|
||||
|MOVING DATA
|
||||
----------------------------------------
|
||||
|
||||
32 - mov n# n#
|
||||
33 - mov n# raw_number
|
||||
34 - mov n# !id
|
||||
35 - mov !id n#
|
||||
|
||||
36 - mov$ s# s#
|
||||
37 - mov$ s# @[data_address]
|
||||
38 - mov$ s# !id
|
||||
39 - mov$ !id s#
|
||||
|
||||
40 - mov_r r# n#
|
||||
41 - mov_r$ r# s#
|
||||
|
||||
42 - mov_type u# u# //copy user types and arrays NOTE: This will do the same thing mov_r does by setting the reference pointed to by the first arg
|
||||
|
||||
--------------------------------------
|
||||
|OPERATORS
|
||||
-------------------------------------
|
||||
|
||||
43 - add$ s# s#
|
||||
|
||||
44 - add n# n#
|
||||
45 - sub n# n#
|
||||
46 - mul n# n#
|
||||
47 - div n# n#
|
||||
48 - pow n# n#
|
||||
49 - mod n# n#
|
||||
50 - shl n# n#
|
||||
51 - shr n# n#
|
||||
52 - and n# n#
|
||||
53 - or n# n#
|
||||
54 - xor n# n#
|
||||
55 - not n# n#
|
||||
|
||||
--------------------------------------
|
||||
|COMPARE AND JUMP
|
||||
--------------------------------------
|
||||
CMP_EQUAL
|
||||
CMP_NOT_EQUAL
|
||||
CMP_GREATER
|
||||
CMP_GREATER_EQUAL
|
||||
CMP_LESS
|
||||
CMP_LESS_EQUAL
|
||||
-------------------------------------
|
||||
|
||||
56 - cmp n# n#
|
||||
57 - cmp$ s# s#
|
||||
58 - cmp_u n# n#
|
||||
|
||||
59 - jmp n#
|
||||
60 - jmp @[address]
|
||||
61 - je n#
|
||||
62 - je @[address]
|
||||
63 - jne n#
|
||||
64 - jne @[address]
|
||||
65 - jg n#
|
||||
66 - jg @[address]
|
||||
67 - jge n#
|
||||
68 - jge @[address]
|
||||
69 - jl n#
|
||||
70 - jl @[address]
|
||||
71 - jle n#
|
||||
72 - jle @[address]
|
||||
|
||||
--------------------------------------
|
||||
|OBJECTS (USER TYPES AND ARRAYS)
|
||||
--------------------------------------
|
||||
OBJ_CURRENT_POSITION
|
||||
OBJ_CURRENT_TYPE
|
||||
--------------------------------------
|
||||
|
||||
73 - obj_num !id
|
||||
74 - obj_num1 !id n# (n# is the first dimension)
|
||||
75 - obj_num2 !id n# n#
|
||||
76 - obj_num3 !id n# n# n#
|
||||
|
||||
77 - obj_str !id
|
||||
78 - obj_str1 !id n# (n# is the first dimension)
|
||||
79 - obj_str2 !id n# n#
|
||||
80 - obj_str3 !id n# n# n#
|
||||
|
||||
81 - obj_usr !id
|
||||
82 - obj_usr1 !id n# (n# is the first dimension)
|
||||
83 - obj_usr2 !id n# n#
|
||||
84 - obj_usr3 !id n# n# n#
|
||||
|
||||
85 - obj_get n#
|
||||
86 - obj_get$ s#
|
||||
|
||||
87 - obj_set n#
|
||||
88 - obj_set s$
|
||||
|
||||
89 - clear_obj
|
||||
|
||||
90 - dim_type !id raw_number (user_type)
|
||||
91 - dim_type1 !id raw_number (user type) n# (dim1)
|
||||
92 - dim_type2 !id raw_number (user type) n# (dim1) n# (dim2)
|
||||
93 - dim_type3 !id raw_number (user type) n# (dim1) n# (dim2) n# (dim3)
|
||||
|
||||
94 - dim_num1 !id n# (dim1)
|
||||
95 - dim_num2 !id n# (dim1) n# (dim2)
|
||||
96 - dim_num3 !id n# (dim1) n# (dim2) n# (dim3)
|
||||
|
||||
97 - dim_str1 !id n# (dim1)
|
||||
98 - dim_str2 !id n# (dim1) n# (dim2)
|
||||
99 - dim_str3 !id n# (dim1) n# (dim2) n# (dim3)
|
||||
|
||||
--------------------------------------------
|
||||
|STACKS
|
||||
--------------------------------------------
|
||||
<STACK> NUM_STACK
|
||||
<STACK> STR_STACK
|
||||
--------------------------------------------
|
||||
|
||||
100 - delete !id
|
||||
101 - delete$ !id
|
||||
|
||||
102 - push n#
|
||||
103 - push !id
|
||||
|
||||
104 - push$ s#
|
||||
105 - push$ !id
|
||||
|
||||
106 - push_empty$
|
||||
|
||||
107 - pop n#
|
||||
108 - pop !id
|
||||
|
||||
109 - pop$ s$
|
||||
110 - pop$ !id
|
||||
|
||||
111 - get_stack_size n#
|
||||
112 - get_stack_size$ n#
|
||||
|
||||
113 - clear_stack
|
||||
114 - clear_stack$
|
||||
|
||||
---------------------------------------------
|
||||
|LOOP
|
||||
---------------------------------------------
|
||||
<STACK> LOOP_STACK
|
||||
---------------------------------------------
|
||||
|
||||
115 - while n#
|
||||
116 - wend @address 'using jmp in parser for now
|
||||
|
||||
117 - for !id n# (starting value) n# (ending value) n#(step value)
|
||||
118 - next @address
|
||||
|
||||
119 - do
|
||||
120 - loop
|
||||
121 - loop_while n#
|
||||
122 - loop_until n#
|
||||
|
||||
123 - pop_loop_stack
|
||||
|
||||
------------------------------------------
|
||||
|FUNCTIONS AND SUB ROUTINES
|
||||
------------------------------------------
|
||||
<STACK> FUNCTION_STACK
|
||||
------------------------------------------
|
||||
|
||||
124 - gosub @[address]
|
||||
125 - return
|
||||
|
||||
-----------------------------------------
|
||||
|POINTERS
|
||||
-----------------------------------------
|
||||
126 - ptr !id n#
|
||||
127 - ptr$ !id s#
|
||||
|
||||
------------------------------------------
|
||||
|ADDED STUFF 'Because I didn't plan this design that well
|
||||
------------------------------------------
|
||||
|
||||
128 - print n#
|
||||
129 - print$ s#
|
||||
130 - func raw_number (built-in function index)
|
||||
131 - push raw_number
|
||||
132 - println
|
||||
133 - mov n# %CMP_FLAG
|
||||
134 - cmp n# raw_number
|
||||
135 - mov_arr n# !id
|
||||
136 - mov_arr$ s# !id
|
||||
137 - pop_ptr n#
|
||||
138 - preset !id
|
||||
139 - preset$ !id
|
||||
|
||||
140 - redim1 !id n#
|
||||
141 - redim2 !id n# n#
|
||||
142 - redim3 !id n# n# n#
|
||||
|
||||
143 - redim1$ !id n#
|
||||
144 - redim2$ !id n# n#
|
||||
145 - redim3$ !id n# n# n#
|
||||
|
||||
146 - for_offset_arr1 n#
|
||||
147 - for_offset_arr2 n# n#
|
||||
148 - for_offset_arr3 n# n# n#
|
||||
|
||||
149 - for_offset_0
|
||||
|
||||
150 - end_x n#
|
||||
|
||||
151 - lval n#
|
||||
152 - lval !id
|
||||
153 - lval @[address]
|
||||
|
||||
154 - lval$ s#
|
||||
155 - lval$ !id
|
||||
|
||||
// ---- New in 4.0 ---------
|
||||
156 - obj_usr_n !id
|
||||
157 - obj_usr_n1 !id n#
|
||||
158 - obj_usr_n2 !id n# n#
|
||||
159 - obj_usr_n3 !id n# n# n#
|
||||
|
||||
160 - obj_usr_s !id
|
||||
161 - obj_usr_s1 !id n#
|
||||
162 - obj_usr_s2 !id n# n#
|
||||
163 - obj_usr_s3 !id n# n# n#
|
||||
|
||||
164 - obj_usr_get n#
|
||||
165 - obj_usr_get s#
|
||||
166 - obj_usr_get u# // gets the value and sets the reference
|
||||
|
||||
167 - uref_ptr !id u#
|
||||
|
||||
168 - mov_type !id u# //copy user types and arrays
|
||||
|
||||
169 - push_t u#
|
||||
170 - push_t !id
|
||||
|
||||
171 - pop_t u#
|
||||
172 - pop_t !id
|
||||
|
||||
173 - push_t_null
|
||||
|
||||
174 - delete_t !id
|
||||
|
||||
175 - dim_type u# raw_number (user_type)
|
||||
176 - dim_type1 u# raw_number (user type) n# (dim1)
|
||||
177 - dim_type2 u# raw_number (user type) n# (dim1) n# (dim2)
|
||||
178 - dim_type3 u# raw_number (user type) n# (dim1) n# (dim2) n# (dim3)
|
||||
|
||||
179 - dim_tfield raw_number (user_type) raw_number (member_type) raw_number (member_index) raw_number (dimensions) n# (dim1) n# (dim2) n# (dim3)
|
||||
|
||||
180 - obj_usr_init !id
|
||||
181 - obj_usr_init1 !id n# (n# is the first dimension)
|
||||
182 - obj_usr_init2 !id n# n#
|
||||
183 - obj_usr_init3 !id n# n# n#
|
||||
|
||||
184 - obj_usr_init u#
|
||||
185 - obj_usr_init1 u# n# (n# is the first dimension)
|
||||
186 - obj_usr_init2 u# n# n#
|
||||
187 - obj_usr_init3 u# n# n# n#
|
||||
|
||||
188 - preset_t !id raw_number (user_type)
|
||||
189 - preset_t1 !id raw_number (user_type) n#
|
||||
190 - preset_t2 !id raw_number (user_type) n# n#
|
||||
191 - preset_t3 !id raw_number (user_type) n# n# n#
|
||||
|
||||
|
||||
Reference in New Issue
Block a user