diff --git a/bin_win32/inc/algs.mash b/bin_win32/inc/algs.mash index b1f6d77..6e9d8bc 100644 --- a/bin_win32/inc/algs.mash +++ b/bin_win32/inc/algs.mash @@ -1,6 +1,7 @@ // Module with some algorithms uses +uses /* * Quick sorting algorithm implementation. @@ -42,6 +43,64 @@ proc QuickSort(arr): FromToQSort(arr, 0, len(arr) - 1) end +/* + * Multithreaded Quick sorting algorithm implementation. + */ + +proc FromToThrQSort(arr, left, right, lvl, maxlvl): + i ?= left + j ?= right + pivot ?= arr[(left + right) \ 2] + + while i < (j + 1): + while arr[i] < pivot: + i++ + end + + while arr[j] > pivot: + j-- + end + + if i < (j + 1): + tmp ?= arr[i] + arr[i] ?= arr[j] + arr[j] ?= tmp + i++ + j-- + end + end + + if lvl < maxlvl: + if left < j: + ThrL ?= Parallel(FromToThrQSort, arr, copy(left), copy(j), lvl + 1, maxlvl) + end + + if i < right: + ThrR ?= Parallel(FromToThrQSort, arr, copy(i), copy(right), lvl + 1, maxlvl) + end + + try: + ThrL -> WaitFor() + ThrR -> WaitFor() + ThrL -> Free() + ThrR -> Free() + catch: + pop + end + else: + if left < j: + FromToThrQSort(arr, left, j, lvl, maxlvl) + end + + if i < right: + FromToThrQSort(arr, i, right, lvl, maxlvl) + end + end +end + +proc ThrQuickSort(arr, maxthr): + FromToThrQSort(arr, 0, len(arr) - 1, 0, maxthr \ 2) +end /* * Heap sorting algorithm implementation. @@ -93,3 +152,70 @@ proc HeapSort(arr): end arr[0] ?= t end + +/* + * Binary search + */ + +func FromToBinSearch(arr, left, right, key): + while true: + midd ?= (left + right) \ 2 + + if key < arr[midd]: + right ?= midd - 1 + else: + if key > arr[midd]: + left ?= midd + 1 + else: + return midd + end + end + + if left > right: + return -1 + end + end +end + +func BinSearch(arr, key): + l ?= len(arr) + if l > 0: + return FromToBinSearch(arr, 0, l - 1, key) + else: + return -1 + end +end + +func FromToBinNext(arr, left, right, key): + while true: + midd ?= (left + right) \ 2 + + if key < arr[midd]: + right ?= midd - 1 + else: + if key > arr[midd]: + left ?= midd + 1 + else: + return midd + end + end + + if left > right: + return midd + end + end +end + +func BinNext(arr, key): + l ?= len(arr) + if l > 0: + r ?= FromToBinNext(arr, 0, l - 1, key) + if arr[r] > key: + return r + else: + return r + 1 + end + else: + return 0 + end +end diff --git a/bin_win32/inc/bf.mash b/bin_win32/inc/bf.mash index 886357e..d3ad26c 100644 --- a/bin_win32/inc/bf.mash +++ b/bin_win32/inc/bf.mash @@ -20,7 +20,7 @@ int false 0 var null = "null" -func BoolToStr(b): +func b2s(b): if b == true: return "true" else: @@ -59,7 +59,8 @@ proc SizeOf(obj): gpm end -enum Types [TypeNull, TypeWord, TypeInt, TypeReal, TypeStr, TypeArray] +enum Types [TypeNull, TypeWord, TypeInt, TypeReal, TypeStr, TypeArray, TypeClass] +word TypePtr 255 proc TypeOf(obj): push obj @@ -120,7 +121,6 @@ end {_end_} func _op_in(v, array): - var i, ln i ?= 0 ln ?= len(array) while i < ln: @@ -132,16 +132,24 @@ func _op_in(v, array): return false end +func ptr(a): + return @a +end + func temp(): return 0 end -proc GetError(): - //err already in stack & already markered +func if(bool, a, b): + if bool: + return a + else: + return b + end end -proc Exit(): - jr +proc GetError(): + //err already in stack & already markered end var ParamCount, ParamList diff --git a/bin_win32/inc/classes.mash b/bin_win32/inc/classes.mash index fa0dc73..31f81bf 100644 --- a/bin_win32/inc/classes.mash +++ b/bin_win32/inc/classes.mash @@ -1,128 +1,14 @@ // Mash lang classes unit -// Code version: 10 +// Code version: 1.0 uses -class class: // for free class-methods declaration -end // like: proc class::MyProc() -- for that --> MyClass->MyMethod = class::MyProc +uses -//////////////////////////////////////////////////////////////////////////////// -// Point -//////////////////////////////////////////////////////////////////////////////// - -class point: - public: - var x, y - proc Create, Free, Set, Compare -end - -proc point::Create(x, y): - $x ?= new(x) - $y ?= new(y) -end - -proc point::Free(): - Free($x, $y, $) -end - -proc point::Set(x, y): - $x = x - $y = y -end - -func point::Compare(p): - return ($x == p->x) & ($y == p->y) -end - -class point3(point): - public: - var z - proc Create, Free - func Compare -end - -proc point3::Create(x, y, z): - point::Create$(x, y) - $z ?= new(z) -end - -proc point3::Free(): - Free($z) - point::Free$() -end - -func point3::Compare(p): - return ($z == p->z) & point::Compare$(p) -end - -//////////////////////////////////////////////////////////////////////////////// -// Vector -//////////////////////////////////////////////////////////////////////////////// - -class vector: - public: - var Items - proc Create, Free, Push_Back, Rem_Back, Rem_First - func Pop_Back, Pop_First, Peek_Back, Peek_First, At, Size -end - -proc vector::Create(): - $Items ?= new[1] - $Items[0] ?= new(0) -end - -proc vector::Push_Back(Object): - SetLen($Items, $Items[0] + 2) - $Items[0]++ - $Items[$Items[0]] ?= Object -end - -func vector::Pop_Back(): - var r = $Items[$Items[0]] - SetLen($Items, $Items[0]) - $Items[0]-- - return r -end - -func vector::Pop_First(): - var r = $Items[1] - for(var i = copy(1); i < $Items[0]; i++): - $Items[i] ?= $Items[i + 1] - end - SetLen($Items, $Items[0]) - $Items[0]-- - return r -end - -func vector::Peek_Back(): - return $Items[$Items[0]] -end - -func vector::Peek_First(): - return $Items[1] -end - -proc vector::Rem_First(): - for(var i = copy(1); i < $Items[0]; i++): - $Items[i] ?= $Items[i + 1] - end - SetLen($Items, $Items[0]) - $Items[0]-- -end - -proc vector::Rem_Back(): - SetLen($Items, $Items[0]) - $Items[0]-- -end - -func vector::At(Index): - return $Items[Index - 1] -end - -func vector::Size(): - return $Items[0] -end - -proc vector::Free(): - Free($Items[0], $Items, $) -end +uses +uses +uses +uses +uses +uses +uses diff --git a/bin_win32/inc/classes/list.mash b/bin_win32/inc/classes/list.mash new file mode 100644 index 0000000..c21a09e --- /dev/null +++ b/bin_win32/inc/classes/list.mash @@ -0,0 +1,107 @@ +//////////////////////////////////////////////////////////////////////////////// +// List +//////////////////////////////////////////////////////////////////////////////// + +uses + +class List(class): + protected: + var Items, Size + + public: + proc Create, Free + + proc Add, Insert, Delete, Clear + func Get, IndexOf + + proc Sort + func NextIns, Find +end + + +proc List::Create(): + $Items ?= new[0] + $Size ?= new(0) +end + + +proc List::Free(): + Free($Items, $Size, $) +end + + +proc List::Add(Obj): + SetLen($Items, $Size + 1) + $Items[$Size] ?= Obj + $Size++ +end + + +proc List::Insert(Obj, Index): + if ($Size < Index) | (Index < 0): + raise "List index (" + Index + ") out of bounds." + else: + $Size++ + SetLen($Items, $Size) + for(i ?= $Size - 1; i > Index; i--): + $Items[i] ?= $Items[i - 1] + end + $Items[Index] ?= Obj + end +end + + +proc List::Delete(Index): + if ($Size <= Index) | (Index < 0): + raise "List index (" + Index + ") out of bounds." + else: + $Size-- + for(; Index < $Size; Index++): + $Items[Index] ?= $Items[Index + 1] + end + SetLen($Items, $Size) + end +end + + +proc List::Clear(): + SetLen($Items, 0) + $Size = 0 +end + + +func List::Get(Index): + return $Items[Index] +end + + +func List::IndexOf(Obj): + if typeof(Obj) in [TypeArray, TypeClass]: + p ?= @Obj + for(i ?= 0; i < $Size; i++): + if p == @$Items[i]: + return i + end + end + else: + for(i ?= 0; i < $Size; i++): + if Obj == $Items[i]: + return i + end + end + end +end + +proc List::Sort(): + QuickSort($Items) +end + +func List::NextIns(Obj): + Indx ?= BinNext($Items, Obj) + $Insert(Obj, Indx) + return Indx +end + +func List::Find(Obj): + return BinSearch($Items, Obj) +end diff --git a/bin_win32/inc/classes/map.mash b/bin_win32/inc/classes/map.mash new file mode 100644 index 0000000..f430a88 --- /dev/null +++ b/bin_win32/inc/classes/map.mash @@ -0,0 +1,118 @@ +//////////////////////////////////////////////////////////////////////////////// +// Map +//////////////////////////////////////////////////////////////////////////////// + +uses + +class Map(class): + protected: + var Objects, Keys + + public: + proc Create, Free + + proc Add, Delete, DeleteAt, Clear + func Get, At, KeyAt, IndexOf, KeyIndexOf, Size +end + +proc Map::Create(): + $Objects ?= new list() + $Keys ?= new list() +end + +proc Map::Free(): + $Objects -> Free() + $Keys -> Free() + Free($) +end + + +proc Map::Add(Obj, Key): + $Objects -> Insert(Obj, $Keys -> NextIns(Key)) +end + +proc Map::Delete(Key): + Indx ?= $Keys -> Find(Key) + $Keys -> Delete(Indx) + $Objects -> Delete(Indx) +end + +proc Map::DeleteAt(Index): + $Keys -> Delete(Index) + $Objects -> Delete(Index) +end + +proc Map::Clear(): + $Keys -> Clear() + $Objects -> Clear() +end + + +func Map::Get(Key): + return $Objects -> Items[$Keys -> Find(Key)] +end + +func Map::At(Index): + return $Objects -> Items[Index] +end + +func Map::KeyAt(Index): + return $Keys -> Items[Index] +end + +func Map::IndexOf(Obj): + return $Objects -> IndexOf(Obj) +end + +func Map::KeyIndexOf(Key): + return $Keys -> Find(Key) +end + +func Map::Size(): + return copy($Keys -> Size) +end + +//////////////////////////////////////////////////////////////////////////////// +// HashMap +//////////////////////////////////////////////////////////////////////////////// + +class HashMap(Map): + public: + proc Add + func IndexOf +end + +proc HashMap::Add(obj): + Map::Add$(obj, obj -> GetHash()) +end + +func HashMap::IndexOf(obj): + return $KeyIndexOf(obj -> GetHash()) +end + +//////////////////////////////////////////////////////////////////////////////// +// StringMap +//////////////////////////////////////////////////////////////////////////////// + +class StringMap(Map): + public: + proc Add + func IndexOf +end + +func GetStrHash(s): + l ?= len(s) + r ?= copy(l) + for(i ?= 1; i <= l; i++): + r = (r * i + l) ^ s[i] + end + return r +end + +proc StringMap::Add(s): + Map::Add$(s, GetStrHash(s)) +end + +func StringMap::IndexOf(s): + return $KeyIndexOf(GetStrHash(s)) +end diff --git a/bin_win32/inc/classes/points.mash b/bin_win32/inc/classes/points.mash new file mode 100644 index 0000000..716bcf3 --- /dev/null +++ b/bin_win32/inc/classes/points.mash @@ -0,0 +1,48 @@ +//////////////////////////////////////////////////////////////////////////////// +// Point's +//////////////////////////////////////////////////////////////////////////////// + +class point(class): + public: + var x, y + proc Create, Free, Set, Compare +end + +proc point::Create(x, y): + $x ?= new(x) + $y ?= new(y) +end + +proc point::Free(): + Free($x, $y, $) +end + +proc point::Set(x, y): + $x = x + $y = y +end + +func point::Compare(p): + return ($x == p->x) & ($y == p->y) +end + +class point3(point): + public: + var z + proc Create, Free + func Compare +end + +proc point3::Create(x, y, z): + point::Create$(x, y) + $z ?= new(z) +end + +proc point3::Free(): + Free($z) + point::Free$() +end + +func point3::Compare(p): + return ($z == p->z) & point::Compare$(p) +end diff --git a/bin_win32/inc/classes/streams.mash b/bin_win32/inc/classes/streams.mash new file mode 100644 index 0000000..22e9a91 --- /dev/null +++ b/bin_win32/inc/classes/streams.mash @@ -0,0 +1,271 @@ +//////////////////////////////////////////////////////////////////////////////// +// Mash streams +//////////////////////////////////////////////////////////////////////////////// + +uses + +// imports + +import _Stream_Create "streams.lib" "_Stream_Create" +import _Stream_Seek "streams.lib" "_Stream_Seek" +import _Stream_GetCaretPos "streams.lib" "_Stream_GetCaretPos" +import _Stream_WriteFromMemoryStream "streams.lib" "_Stream_WriteFromStream" +import _Stream_ReadFromMemoryStream "streams.lib" "_Stream_ReadFromStream" +import _Stream_CopyFromStream "streams.lib" "_Stream_CopyFromStream" +import _Stream_WriteByte "streams.lib" "_Stream_WriteByte" +import _Stream_WriteWord "streams.lib" "_Stream_WriteWord" +import _Stream_WriteInt "streams.lib" "_Stream_WriteInt" +import _Stream_WriteFloat "streams.lib" "_Stream_WriteFloat" +import _Stream_WriteStr "streams.lib" "_Stream_WriteStr" +import _Stream_ReadByte "streams.lib" "_Stream_ReadByte" +import _Stream_ReadWord "streams.lib" "_Stream_ReadWord" +import _Stream_ReadInt "streams.lib" "_Stream_ReadInt" +import _Stream_ReadFloat "streams.lib" "_Stream_ReadFloat" +import _Stream_ReadStr "streams.lib" "_Stream_ReadStr" +import _Stream_GetSize "streams.lib" "_Stream_GetSize" +import _Stream_Clear "streams.lib" "_Stream_Clear" +import _Stream_Free "streams.lib" "_Stream_Free" +import _MemoryStream_Create "streams.lib" "_MemoryStream_Create" +import _MemoryStream_Free "streams.lib" "_MemoryStream_Free" +import _MemoryStream_LoadFromStream "streams.lib" "_MemoryStream_LoadFromStream" +import _MemoryStream_StoreToStream "streams.lib" "_MemoryStream_StoreToStream" +import _MemoryStream_LoadFromFile "streams.lib" "_MemoryStream_LoadFromFile" +import _MemoryStream_SaveToFile "streams.lib" "_MemoryStream_SaveToFile" +import _FileStream_Create "streams.lib" "_FileStream_Create" +import _FileStream_Free "streams.lib" "_FileStream_Free" + +/* + * Base TStream class + */ + +enum TSeekOffset [soStart, soCurrent, soEnd] + +class TStream: + private: + // pointer to external TStream class + var StreamPtr + + public: + // constructor & destructor + proc Create, Free + + // main methods + proc Seek, Clear + func GetCaretPos, GetSize + + // streams operations + proc WriteFromMemoryStream, ReadFromMemoryStream, CopyFromStream + + // writers + proc Write, WriteU, WriteByte, WriteWord, WriteInt, WriteFloat, WriteStr + + // readers + proc ReadByte, ReadWord, ReadInt, ReadFloat, ReadStr +end + +// constructor & destructor + +proc TStream::Create(...): + if argcount > 0: + pop resource + $StreamPtr ?= ?resource + else: + $StreamPtr ?= _Stream_Create() + end +end + +proc TStream::Free(): + _Stream_Free($StreamPtr, $) +end + +// some methods + +proc TStream::Seek(pos, offset): + _Stream_Seek($StreamPtr, pos, offset) +end + +proc TStream::Clear(): + _Stream_Clear($StreamPtr) +end + +func TStream::GetCaretPos(): + return gpmx(_Stream_GetCaretPos($StreamPtr)) +end + +func TStream::GetSize(): + return gpmx(_Stream_GetSize($StreamPtr)) +end + +// stream operations + +proc TStream::WriteFromMemoryStream(mstream, size): + _Stream_WriteFromMemoryStream($StreamPtr, mstream, size) +end + +proc TStream::ReadFromMemoryStream(mstream, size): + _Stream_ReadFromMemoryStream($StreamPtr, mstream, size) +end + +proc TStream::CopyFromStream(mstream, size): + _Stream_ReadFromMemoryStream($StreamPtr, mstream, size) +end + +// writers + +proc TStream::Write(): + var t + t ?= argcount + while t > 0: + $WriteU() + dec t + end +end + +proc TStream::WriteU(value): + switch typeof(value): + + case typeWord: + $WriteWord(value) + break + end + + case typeInt: + $WriteInt(value) + break + end + + case typeReal: + $WriteFloat(value) + break + end + + case typeStr: + $WriteStr(value) + break + end + + else: + raise "With TStream: I/O error, invalid type cast!" + end +end + +proc TStream::WriteByte(value): + _Stream_WriteByte($StreamPtr, value) +end + +proc TStream::WriteWord(value): + _Stream_WriteWord($StreamPtr, value) +end + +proc TStream::WriteInt(value): + _Stream_WriteInt($StreamPtr, value) +end + +proc TStream::WriteFloat(value): + _Stream_WriteFloat($StreamPtr, value) +end + +proc TStream::WriteStr(value): + _Stream_WriteStr($StreamPtr, value) +end + +// readers + +proc TStream::ReadByte(value): + _Stream_ReadByte($StreamPtr, value) +end + +proc TStream::ReadWord(value): + _Stream_ReadWord($StreamPtr, value) +end + +proc TStream::ReadInt(value): + _Stream_ReadInt($StreamPtr, value) +end + +proc TStream::ReadFloat(value): + _Stream_ReadFloat($StreamPtr, value) +end + +proc TStream::ReadStr(value, ln): + _Stream_ReadStr($StreamPtr, value, ln) +end + +/* + * TMemoryStream class + */ + +class TMemoryStream(TStream): + public: + // constructor & destructor + proc Create, Free + + // some methods + proc LoadFromStream, StoreToStream, LoadFromFile, SaveToFile +end + +// constructor & destructor + +proc TMemoryStream::Create(...): + if argcount > 0: + pop resource + $StreamPtr ?= ?resource + else: + $StreamPtr ?= _MemoryStream_Create() + end +end + +proc TMemoryStream::Free(): + _MemoryStream_Free($StreamPtr, $) +end + +// some methods + +proc TMemoryStream::LoadFromStream(mstream): + _MemoryStream_LoadFromStream($StreamPtr, mstream) +end + +proc TMemoryStream::StoreToStream(mstream): + _MemoryStream_StoreToStream($StreamPtr, mstream) +end + +proc TMemoryStream::LoadFromFile(fpath): + _MemoryStream_LoadFromFile($StreamPtr, fpath) +end + +proc TMemoryStream::SaveToFile(fpath): + _MemoryStream_SaveToFile($StreamPtr, fpath) +end + +/* + * TFileStream + */ + +class TFileStream(TStream): + public: + // constructor & destructor + proc Create, Free +end + +// TFileStream modes + +word fmCreate 0xFF00 +word fmOpenRead 0x0000 +word fmOpenWrite 0x0001 +word fmOpenReadWrite 0x0002 + +word fmShareCompat 0x0000 +word fmShareExclusive 0x0010 +word fmShareDenyWrite 0x0020 +word fmShareDenyRead 0x0030 +word fmShareDenyNone 0x0040 + +// constructor & destructor + +proc TFileStream::Create(fpath, openmode): + $StreamPtr ?= _FileStream_Create(fpath, openmode) +end + +proc TFileStream::Free(): + _FileStream_Free($StreamPtr, $) +end diff --git a/bin_win32/inc/classes/stringlist.mash b/bin_win32/inc/classes/stringlist.mash new file mode 100644 index 0000000..69d2b3c --- /dev/null +++ b/bin_win32/inc/classes/stringlist.mash @@ -0,0 +1,62 @@ +//////////////////////////////////////////////////////////////////////////////// +// Base types +//////////////////////////////////////////////////////////////////////////////// + +uses +uses +uses + +class StringList(List): + public: + proc SetText, SaveToFile, LoadFromFile + func GetText +end + +proc StringList::SetText(text): + $Clear() + p ?= s_Pos(LnBreak, text) + while p > 0: + $Add(s_Copy(text, 1, p - 1)) + s_Del(text, 1, p + len(LnBreak) - 1) + p ?= s_Pos(LnBreak, text) + end + if Len(text) > 0: + $Add(text) + end +end + +func StringList::GetText(): + r ?= "" + for(i ?= 0; i < $size; i++): + r += $Items[i] + if i + 1 < $size: + r += LnBreak + end + end + return r +end + +proc StringList::SaveToFile(fpath): + st ?= new TFileStream(fpath, fmCreate) + st -> WriteStr($GetText()) + st -> Free() +end + +proc StringList::LoadFromFile(fpath): + st ?= new TFileStream(fpath, fmOpenRead) + s ?= "" + sz ?= st -> GetSize() + st -> ReadStr(s, sz) + st -> Free() + + $Clear() + p ?= s_Pos(LnBreak, s) + while p > 0: + $Add(s_Copy(s, 1, p - 1)) + s_Del(s, 1, p + len(LnBreak)) + p ?= s_Pos(LnBreak, s) + end + if Len(s) > 0: + $Add(s) + end +end diff --git a/bin_win32/inc/classes/tree.mash b/bin_win32/inc/classes/tree.mash new file mode 100644 index 0000000..a84b01f --- /dev/null +++ b/bin_win32/inc/classes/tree.mash @@ -0,0 +1,54 @@ +//////////////////////////////////////////////////////////////////////////////// +// Tree +//////////////////////////////////////////////////////////////////////////////// + +class Tree(class): + protected: + var Nodes, Count + + public: + var Value + proc Create, Free + + func AddNode, GetNode + proc DelNode +end + +proc Tree::Create(val): + $Nodes ?= new[0] + $Count ?= new(0) + $Value ?= val +end + +proc Tree::Free(): + while $Count > 0: + $Count-- + $Nodes[$Count] -> Free() + end + Free($Nodes, $Count, $) +end + +func Tree::AddNode(val): + SetLen($Nodes, $Count + 1) + n ?= new Tree(val) + $Nodes[$Count] ?= n + $Count++ + return n +end + +func Tree::GetNode(num): + return $Nodes[num] +end + +proc Tree::DelNode(num): + if ($Count <= num) | (num < 0): + raise "Tree node number (" + num + ") out of bounds." + else: + $Count-- + $Nodes[num] -> Free() + for(; num < $Count; num++): + $Nodes[num] ?= $Nodes[num + 1] + end + SetLen($Nodes, $Count) + end +end diff --git a/bin_win32/inc/classes/types.mash b/bin_win32/inc/classes/types.mash new file mode 100644 index 0000000..b3a6fe1 --- /dev/null +++ b/bin_win32/inc/classes/types.mash @@ -0,0 +1,13 @@ +//////////////////////////////////////////////////////////////////////////////// +// Base types +//////////////////////////////////////////////////////////////////////////////// + +uses + +class class: + func GetHash +end + +func class::GetHash(): + return (len($) ^ ptr($)) * $type +end diff --git a/bin_win32/inc/classes/vector.mash b/bin_win32/inc/classes/vector.mash new file mode 100644 index 0000000..4cf49a4 --- /dev/null +++ b/bin_win32/inc/classes/vector.mash @@ -0,0 +1,71 @@ +//////////////////////////////////////////////////////////////////////////////// +// Vector +//////////////////////////////////////////////////////////////////////////////// + +class vector(class): + public: + var Items + proc Create, Free, Push_Back, Rem_Back, Rem_First + func Pop_Back, Pop_First, Peek_Back, Peek_First, At, Size +end + +proc vector::Create(): + $Items ?= new[1] + $Items[0] ?= new(0) +end + +proc vector::Push_Back(Object): + SetLen($Items, $Items[0] + 2) + $Items[0]++ + $Items[$Items[0]] ?= Object +end + +func vector::Pop_Back(): + var r = $Items[$Items[0]] + SetLen($Items, $Items[0]) + $Items[0]-- + return r +end + +func vector::Pop_First(): + var r = $Items[1] + for(var i = copy(1); i < $Items[0]; i++): + $Items[i] ?= $Items[i + 1] + end + SetLen($Items, $Items[0]) + $Items[0]-- + return r +end + +func vector::Peek_Back(): + return $Items[$Items[0]] +end + +func vector::Peek_First(): + return $Items[1] +end + +proc vector::Rem_First(): + for(var i = copy(1); i < $Items[0]; i++): + $Items[i] ?= $Items[i + 1] + end + SetLen($Items, $Items[0]) + $Items[0]-- +end + +proc vector::Rem_Back(): + SetLen($Items, $Items[0]) + $Items[0]-- +end + +func vector::At(Index): + return $Items[Index - 1] +end + +func vector::Size(): + return $Items[0] +end + +proc vector::Free(): + Free($Items[0], $Items, $) +end diff --git a/bin_win32/inc/crt.mash b/bin_win32/inc/crt.mash index c04b6a1..f93ba8c 100644 --- a/bin_win32/inc/crt.mash +++ b/bin_win32/inc/crt.mash @@ -1,29 +1,33 @@ -import Crt.CursorBig "crt.lib" "CURSORBIG" -import Crt.CursorOff "crt.lib" "CURSOROFF" -import Crt.CursorOn "crt.lib" "CURSORON" -import Crt.DelLine "crt.lib" "DELLINE" -import Crt.GotoXY32 "crt.lib" "GOTOXY32" -import Crt.InsLine "crt.lib" "INSLINE" -import Crt.KeyPressed "crt.lib" "KEYPRESSED" -import Crt.ReadKey "crt.lib" "READKEY" -import Crt.Sound "crt.lib" "SOUND" -import Crt.WhereX32 "crt.lib" "WHEREX32" -import Crt.WhereY32 "crt.lib" "WHEREY32" -import Crt.Window32 "crt.lib" "WINDOW32" -import Crt.ClrEOL "crt.lib" "CLREOL" -import Crt.ClrScr "crt.lib" "CLRSCR" -import Crt.GetDirectVideo "crt.lib" "GETDIRECTVIDEO" -import Crt.GetLastMode "crt.lib" "GETLASTMODE" -import Crt.GetTextAttr "crt.lib" "GETTEXTATTR" -import Crt.GetWindMax "crt.lib" "GETWINDMAX" -import Crt.GetWindMaxX "crt.lib" "GETWINDMAXX" -import Crt.GetWindMaxY "crt.lib" "GETWINDMAXY" -import Crt.GetWindMin "crt.lib" "GETWINDMIN" -import Crt.GetWindMinX "crt.lib" "GETWINDMINX" -import Crt.GetWindMinY "crt.lib" "GETWINDMINY" -import Crt.GetCheckBreak "crt.lib" "GETCHECKBREAK" -import Crt.GetCheckEOF "crt.lib" "GETCHECKEOF" -import Crt.GetCheckSnow "crt.lib" "GETCHECKSNOW" +import Crt.CursorBig "crt.lib" "CURSORBIG" +import Crt.CursorOff "crt.lib" "CURSOROFF" +import Crt.CursorOn "crt.lib" "CURSORON" +import Crt.DelLine "crt.lib" "DELLINE" +import Crt.GotoXY32 "crt.lib" "GOTOXY32" +import Crt.InsLine "crt.lib" "INSLINE" +import _Crt.KeyPressed "crt.lib" "KEYPRESSED" +import _Crt.ReadKey "crt.lib" "READKEY" +import Crt.Sound "crt.lib" "SOUND" +import _Crt.WhereX32 "crt.lib" "WHEREX32" +import _Crt.WhereY32 "crt.lib" "WHEREY32" +import Crt.Window32 "crt.lib" "WINDOW32" +import Crt.ClrEOL "crt.lib" "CLREOL" +import Crt.ClrScr "crt.lib" "CLRSCR" +import _Crt.GetDirectVideo "crt.lib" "GETDIRECTVIDEO" +import _Crt.GetLastMode "crt.lib" "GETLASTMODE" +import Crt.SetTextAttr "crt.lib" "SETTEXTATTR" +import _Crt.GetTextAttr "crt.lib" "GETTEXTATTR" +import _Crt.GetWindMax "crt.lib" "GETWINDMAX" +import _Crt.GetWindMaxX "crt.lib" "GETWINDMAXX" +import _Crt.GetWindMaxY "crt.lib" "GETWINDMAXY" +import _Crt.GetWindMin "crt.lib" "GETWINDMIN" +import _Crt.GetWindMinX "crt.lib" "GETWINDMINX" +import _Crt.GetWindMinY "crt.lib" "GETWINDMINY" +import _Crt.GetCheckBreak "crt.lib" "GETCHECKBREAK" +import _Crt.GetCheckEOF "crt.lib" "GETCHECKEOF" +import _Crt.GetCheckSnow "crt.lib" "GETCHECKSNOW" +import Crt.TextColor "crt.lib" "SETTEXTCOLOR" +import Crt.TextBackground "crt.lib" "SETTEXTBACKGROUND" + {_ifdef_ argcounter} import _Print "crt.lib" "PRINT" @@ -35,17 +39,16 @@ import Print "crt.lib" "PRINT" import PrintLn "crt.lib" "PRINTLN" {_end_} -import PrintFormat "crt.lib" "PRINTFORMAT" -import Input "crt.lib" "INPUT" -import InputLn "crt.lib" "INPUTLN" +import _Input "crt.lib" "INPUT" +import _InputLn "crt.lib" "INPUTLN" // CRT modes -word Crt.BW40 0 // 40x25 B/W on Color Adapter -word Crt.CO40 1 // 40x25 Color on Color Adapter -word Crt.BW80 2 // 80x25 B/W on Color Adapter -word Crt.CO80 3 // 80x25 Color on Color Adapter -word Crt.Mono 7 // 80x25 on Monochrome Adapter -word Crt.Font8x8 256 // Add-in for ROM font +word Crt.BW40 0 // 40x25 B/W on Color Adapter +word Crt.CO40 1 // 40x25 Color on Color Adapter +word Crt.BW80 2 // 80x25 B/W on Color Adapter +word Crt.CO80 3 // 80x25 Color on Color Adapter +word Crt.Mono 7 // 80x25 on Monochrome Adapter +word Crt.Font8x8 256 // Add-in for ROM font // Foreground and background color constants word Crt.Black 0 @@ -75,93 +78,109 @@ word Crt.Blink 128 {_ifdef_ argcounter} proc print(...): - var t t ?= argcount while t > 0: _print() - dec t + t-- end end proc println(...): - var t t ?= argcount while t > 0: _print() - dec t + t-- end _println("") end {_end_} -//var Crt.TextAttr - -//proc Crt.Init(): -// Crt.TextAttr = new(0x07) -//end - -//proc Crt.TextColor(.color): -// and .color, 143 -// and Crt.TextAttr, 112 -// or Crt.TextAttr, .color -//end - -//proc Crt.TextBackground(.color): -//var .buf = 0xf0 -// store(.color) -// and .buf, .color -// shl .color, 4 -// and .color, .buf -// mov .buf, 0x0f -// or .buf, !Crt.Blink -// and .buf, Crt.TextAttr -// or .color, .buf -// mov Crt.TextAttr, .color -// load(.color) -//end - -//proc Crt.NormVideo(): -// push 7 -// Crt.TextColor() -// push 0 -// Crt.TextBackGround() -//end - -//proc Crt.WhereX(): -// Crt.WhereX32() -// push 256 -// gpm -// swp -// mod -//end - -//proc Crt.WhereY(): -// Crt.WhereY32() -// push 256 -// gpm -// swp -// mod -//end - -//proc Crt.Pause(): -// gc -// Crt.KeyPressed() -// gpm -// jz !Crt.Pause -//end - -//proc PrintFmt(): -// push .Crt.TextAttr -// swp -// PrintFormat() -//end - -//proc PrintLnFmt(): -// push Crt.TextAttr -// swp -// PrintFormat() -// push "" -// gpm -// PrintLn() -//end +func Crt.KeyPressed(): + return gpmx(_Crt.KeyPressed()) +end + +func Crt.ReadKey(): + return gpmx(_Crt.ReadKey()) +end + +func Crt.WhereX32(): + return gpmx(_Crt.WhereX32()) +end + +func Crt.WhereY32(): + return gpmx(_Crt.WhereY32()) +end + +func Crt.GetDirectVideo(): + return gpmx(_Crt.GetDirectVideo()) +end + +func Crt.GetLastMode(): + return gpmx(_Crt.GetLastMode()) +end + +func Crt.GetTextAttr(): + return gpmx(_Crt.GetTextAttr()) +end + +func Crt.GetWindMax(): + return gpmx(_Crt.GetWindMax()) +end + +func Crt.GetWindMaxX(): + return gpmx(_Crt.GetWindMaxX()) +end + +func Crt.GetWindMaxY(): + return gpmx(_Crt.GetWindMaxY()) +end + +func Crt.GetWindMin(): + return gpmx(_Crt.GetWindMin()) +end + +func Crt.GetWindMinX(): + return gpmx(_Crt.GetWindMinX()) +end + +func Crt.GetWindMinY(): + return gpmx(_Crt.GetWindMinY()) +end + +func Crt.GetCheckBreak(): + return gpmx(_Crt.GetCheckBreak()) +end + +func Crt.GetCheckEOF(): + return gpmx(_Crt.GetCheckEOF()) +end + +func Crt.GetCheckSnow(): + return gpmx(_Crt.GetCheckSnow()) +end + +func Input(): + return gpmx(_Input()) +end + +func InputLn(): + return gpmx(_InputLn()) +end + +proc Crt.NormVideo(): + Crt.TextColor(7) + Crt.TextBackGround(0) +end + +func Crt.WhereX(): + return Crt.WhereX32() % 256 +end + +func Crt.WhereY(): + return Crt.WhereY32() % 256 +end + +proc Crt.Pause(): + Crt.ReadKey() +end diff --git a/bin_win32/inc/threads.mash b/bin_win32/inc/threads.mash index 278e1f2..cd47a15 100644 --- a/bin_win32/inc/threads.mash +++ b/bin_win32/inc/threads.mash @@ -2,20 +2,28 @@ // Code version: 1.0 uses +uses + +// imports from thrlib + +import __CRITSECT_CREATE "thrlib.lib" "CRITICAL_SECTION_CREATE" +import __CRITSECT_FREE "thrlib.lib" "CRITICAL_SECTION_FREE" +import __CRITSECT_ENTER "thrlib.lib" "CRITICAL_SECTION_ENTER" +import __CRITSECT_LEAVE "thrlib.lib" "CRITICAL_SECTION_LEAVE" +import __CRITSECT_TRYENTER "thrlib.lib" "CRITICAL_SECTION_TRYENTER" // common methods -proc thread(method, arg): +proc thr_create(method, arg): push arg push method cthr end -proc async(method, arg): +proc thr_async(method, arg): push arg push method cthr - pcopy rthr end @@ -44,11 +52,15 @@ end //////////////////////////////////////////////////////////////////////////////// class TThread: - public: - var Resumed, Terminated, FreeOnTerminate - proc Execute, Create, Free, Suspend, Resume, Terminate, ReJoin protected: var ThreadContext + + public: + var Resumed, Terminated, FreeOnTerminate + proc Create, Free + + proc Execute //for overriding + proc Suspend, Resume, Terminate, WaitFor, ReJoin //Control proc's end proc TThread::Execute(): @@ -57,17 +69,14 @@ end proc TThread_Join(CurrentThreadContext, ThreadClass): ThreadClass->Execute() - ThreadClass->Terminated = true - if ThreadClass->FreeOnTerminate: - ThreadClass->Free() - end + ThreadClass->Terminate() end proc TThread::Create(Resumed): $Resumed ?= new(false) $Terminated ?= new(false) $FreeOnTerminate ?= new(true) - $ThreadContext ?= thread(TThread_Join, $) + $ThreadContext ?= thr_create(TThread_Join, $) if Resumed: $Resume() end @@ -95,9 +104,165 @@ proc TThread::Resume(): end proc TThread::Terminate(): - thr_terminate($ThreadContext) + $Resumed = false $Terminated = true + Ctxt ?= $ThreadContext if $FreeOnTerminate: $Free() end + thr_terminate(Ctxt) +end + +proc TThread::WaitFor(): + FreeOnTerm ?= $FreeOnTerminate + $FreeOnTerminate = false + + while ~$Terminated: + Sleep(0) + end + + if FreeOnTerm: + $Free() + end +end + +//////////////////////////////////////////////////////////////////////////////// +// Critical sections controller class +//////////////////////////////////////////////////////////////////////////////// + +class TCriticalSection: + protected: + var Critical_Section_Controller + + public: + proc Create, Free + + //Methods + proc Enter, Leave + func TryEnter +end + +proc TCriticalSection::Create(): + $Critical_Section_Controller ?= __CRITSECT_CREATE() +end + +proc TCriticalSection::Free(): + __CRITSECT_FREE($Critical_Section_Controller) + Free($) +end + +proc TCriticalSection::Enter(): + __CRITSECT_ENTER($Critical_Section_Controller) +end + +proc TCriticalSection::Leave(): + __CRITSECT_LEAVE($Critical_Section_Controller) +end + +func TCriticalSection::TryEnter(): + return gpmx(__CRITSECT_TRYENTER($Critical_Section_Controller)) +end + +//////////////////////////////////////////////////////////////////////////////// +// Async +//////////////////////////////////////////////////////////////////////////////// + +class TAsyncCallThread(TThread): + var Method, Args + proc Create, Execute +end + +proc TAsyncCallThread::Create(Method, Args): + $Method ?= Method + $Args ?= Args + TThread::Create$(true) +end + +proc TAsyncCallThread::Execute(): + while $Args->Size() > 0: + $Args -> pop_back() + end + $Args->Free() + call $Method +end + +func Async(method, ...): + args ?= new vector() + t ?= argcount + while t > 0: + pop arg + args->push_back(arg) + t-- + end + return new TAsyncCallThread(method, args) +end + +//////////////////////////////////////////////////////////////////////////////// +// QuickThread +//////////////////////////////////////////////////////////////////////////////// + +class TQThreadCallThread(TThread): + var Method, Args + proc Create, Execute +end + +proc TQThreadCallThread::Create(Method, Args): + $Method ?= Method + $Args ?= Args + TThread::Create$(false) +end + +proc TQThreadCallThread::Execute(): + while $Args->Size() > 0: + $Args -> pop_back() + end + $Args->Free() + call $Method +end + +func Thread(method, ...): + args ?= new vector() + t ?= argcount + while t > 0: + pop arg + args->push_back(arg) + t-- + end + return new TQThreadCallThread(method, args) +end + +//////////////////////////////////////////////////////////////////////////////// +// Parallel tasks +//////////////////////////////////////////////////////////////////////////////// + +class TParallelCallThread(TThread): + var Method, Args + proc Create, Execute +end + +proc TParallelCallThread::Create(Method, Args): + $Method ?= Method + $Args ?= Args + TThread::Create$(false) + $FreeOnTerminate = false + $Resume() +end + +proc TParallelCallThread::Execute(): + while $Args->Size() > 0: + $Args -> pop_back() + end + $Args->Free() + call $Method +end + +func Parallel(method, ...): + args ?= new vector() + t ?= argcount + while t > 0: + pop arg + args->push_back(arg) + t-- + end + return new TParallelCallThread(method, args) end