diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index 6b52b301..6b206b98 100644 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -134,6 +134,15 @@ Batchfile: Befunge: primary_extension: .befunge +BlitzBasic: + type: programming + aliases: + - blitzplus + - blitz3d + primary_extension: .bb + extensions: + - .decls + BlitzMax: primary_extension: .bmx diff --git a/samples/BlitzBasic/HalfAndDouble.bb b/samples/BlitzBasic/HalfAndDouble.bb new file mode 100644 index 00000000..6b8aa0d3 --- /dev/null +++ b/samples/BlitzBasic/HalfAndDouble.bb @@ -0,0 +1,147 @@ + +Local bk = CreateBank(8) +PokeFloat bk, 0, -1 +Print Bin(PeekInt(bk, 0)) +Print %1000000000000000 +Print Bin(1 Shl 31) +Print $1f +Print $ff +Print $1f + (127 - 15) +Print Hex(%01111111100000000000000000000000) +Print Hex(~%11111111100000000000000000000000) + +Print Bin(FloatToHalf(-2.5)) +Print HalfToFloat(FloatToHalf(-200000000000.0)) + +Print Bin(FToI(-2.5)) + +WaitKey +End + + +; Half-precision (16-bit) arithmetic library +;============================================ + +Global Half_CBank_ + +Function FToI(f#) + If Half_CBank_ = 0 Then Half_CBank_ = CreateBank(4) + PokeFloat Half_CBank_, 0, f + Return PeekInt(Half_CBank_, 0) +End Function + +Function HalfToFloat#(h) + Local signBit, exponent, fraction, fBits + + signBit = (h And 32768) <> 0 + exponent = (h And %0111110000000000) Shr 10 + fraction = (h And %0000001111111111) + + If exponent = $1F Then exponent = $FF : ElseIf exponent Then exponent = (exponent - 15) + 127 + fBits = (signBit Shl 31) Or (exponent Shl 23) Or (fraction Shl 13) + + If Half_CBank_ = 0 Then Half_CBank_ = CreateBank(4) + PokeInt Half_CBank_, 0, fBits + Return PeekFloat(Half_CBank_, 0) +End Function + +Function FloatToHalf(f#) + Local signBit, exponent, fraction, fBits + + If Half_CBank_ = 0 Then Half_CBank_ = CreateBank(4) + PokeFloat Half_CBank_, 0, f + fBits = PeekInt(Half_CBank_, 0) + + signBit = (fBits And (1 Shl 31)) <> 0 + exponent = (fBits And $7F800000) Shr 23 + fraction = fBits And $007FFFFF + + If exponent + exponent = exponent - 127 + If Abs(exponent) > $1F + If exponent <> ($FF - 127) Then fraction = 0 + exponent = $1F * Sgn(exponent) + Else + exponent = exponent + 15 + EndIf + exponent = exponent And %11111 + EndIf + fraction = fraction Shr 13 + + Return (signBit Shl 15) Or (exponent Shl 10) Or fraction +End Function + +Function HalfAdd(l, r) + +End Function + +Function HalfSub(l, r) + +End Function + +Function HalfMul(l, r) + +End Function + +Function HalfDiv(l, r) + +End Function + +Function HalfLT(l, r) + +End Function + +Function HalfGT(l, r) + +End Function + + +; Double-precision (64-bit) arithmetic library) +;=============================================== + +Global DoubleOut[1], Double_CBank_ + +Function DoubleToFloat#(d[1]) + +End Function + +Function FloatToDouble(f#) + +End Function + +Function IntToDouble(i) + +End Function + +Function SefToDouble(s, e, f) + +End Function + +Function DoubleAdd(l, r) + +End Function + +Function DoubleSub(l, r) + +End Function + +Function DoubleMul(l, r) + +End Function + +Function DoubleDiv(l, r) + +End Function + +Function DoubleLT(l, r) + +End Function + +Function DoubleGT(l, r) + +End Function + + +;~IDEal Editor Parameters: +;~F#1A#20#2F +;~C#Blitz3D \ No newline at end of file diff --git a/samples/BlitzBasic/LList.bb b/samples/BlitzBasic/LList.bb new file mode 100644 index 00000000..49bf4eaa --- /dev/null +++ b/samples/BlitzBasic/LList.bb @@ -0,0 +1,369 @@ + +; Double-linked list container class +;==================================== + +; with thanks to MusicianKool, for concept and issue fixes + + +Type LList + Field head_.ListNode + Field tail_.ListNode +End Type + +Type ListNode + Field pv_.ListNode + Field nx_.ListNode + Field Value +End Type + +Type Iterator + Field Value + Field l_.LList + Field cn_.ListNode, cni_ +End Type + + +;Create a new LList object +Function CreateList.LList() + Local l.LList = New LList + + l\head_ = New ListNode + l\tail_ = New ListNode + + l\head_\nx_ = l\tail_ ;End caps + l\head_\pv_ = l\head_ ;These make it more or less safe to iterate freely + l\head_\Value = 0 + + l\tail_\nx_ = l\tail_ + l\tail_\pv_ = l\head_ + l\tail_\Value = 0 + + Return l +End Function + +;Free a list and all elements (not any values) +Function FreeList(l.LList) + ClearList l + Delete l\head_ + Delete l\tail_ + Delete l +End Function + +;Remove all the elements from a list (does not free values) +Function ClearList(l.LList) + Local n.ListNode = l\head_\nx_ + While n <> l\tail_ + Local nx.ListNode = n\nx_ + Delete n + n = nx + Wend + l\head_\nx_ = l\tail_ + l\tail_\pv_ = l\head_ +End Function + +;Count the number of elements in a list (slow) +Function ListLength(l.LList) + Local i.Iterator = GetIterator(l), elems + While EachIn(i) + elems = elems + 1 + Wend + Return elems +End Function + +;Return True if a list contains a given value +Function ListContains(l.LList, Value) + Return (ListFindNode(l, Value) <> Null) +End Function + +;Create a linked list from the intvalues in a bank (slow) +Function ListFromBank.LList(bank) + Local l.LList = CreateList() + Local size = BankSize(bank), p + + For p = 0 To size - 4 Step 4 + ListAddLast l, PeekInt(bank, p) + Next + + Return l +End Function + +;Create a bank containing all the values in a list (slow) +Function ListToBank(l.LList) + Local size = ListLength(l) * 4 + Local bank = CreateBank(size) + + Local i.Iterator = GetIterator(l), p = 0 + While EachIn(i) + PokeInt bank, p, i\Value + p = p + 4 + Wend + + Return bank +End Function + +;Swap the contents of two list objects +Function SwapLists(l1.LList, l2.LList) + Local tempH.ListNode = l1\head_, tempT.ListNode = l1\tail_ + l1\head_ = l2\head_ + l1\tail_ = l2\tail_ + l2\head_ = tempH + l2\tail_ = tempT +End Function + +;Create a new list containing the same values as the first +Function CopyList.LList(lo.LList) + Local ln.LList = CreateList() + Local i.Iterator = GetIterator(lo) : While EachIn(i) + ListAddLast ln, i\Value + Wend + Return ln +End Function + +;Reverse the order of elements of a list +Function ReverseList(l.LList) + Local n1.ListNode, n2.ListNode, tmp.ListNode + + n1 = l\head_ + n2 = l\head_\nx_ + + While n1 <> l\tail_ + n1\pv_ = n2 + tmp = n2\nx_ + n2\nx_ = n1 + n1 = n2 + n2 = tmp + Wend + + tmp = l\head_ + l\head_ = l\tail_ + l\tail_ = tmp + + l\head_\pv_ = l\head_ + l\tail_\nx_ = l\tail_ +End Function + +;Search a list to retrieve the first node with the given value +Function ListFindNode.ListNode(l.LList, Value) + Local n.ListNode = l\head_\nx_ + + While n <> l\tail_ + If n\Value = Value Then Return n + n = n\nx_ + Wend + + Return Null +End Function + +;Append a value to the end of a list (fast) and return the node +Function ListAddLast.ListNode(l.LList, Value) + Local n.ListNode = New ListNode + + n\pv_ = l\tail_\pv_ + n\nx_ = l\tail_ + n\Value = Value + + l\tail_\pv_ = n + n\pv_\nx_ = n + + Return n +End Function + +;Attach a value to the start of a list (fast) and return the node +Function ListAddFirst.ListNode(l.LList, Value) + Local n.ListNode = New ListNode + + n\pv_ = l\head_ + n\nx_ = l\head_\nx_ + n\Value = Value + + l\head_\nx_ = n + n\nx_\pv_ = n + + Return n +End Function + +;Remove the first occurence of the given value from a list +Function ListRemove(l.LList, Value) + Local n.ListNode = ListFindNode(l, Value) + If n <> Null Then RemoveListNode n +End Function + +;Remove a node from a list +Function RemoveListNode(n.ListNode) + n\pv_\nx_ = n\nx_ + n\nx_\pv_ = n\pv_ + Delete n +End Function + +;Return the value of the element at the given position from the start of the list, +;or backwards from the end of the list for a negative index +Function ValueAtIndex(l.LList, index) + Local n.ListNode = ListNodeAtIndex(l, index) + If n <> Null Then Return n\Value : Else Return 0 +End Function + +;Return the ListNode at the given position from the start of the list, or backwards +;from the end of the list for a negative index, or Null if invalid +Function ListNodeAtIndex.ListNode(l.LList, index) + Local e, n.ListNode + + If index >= 0 + n = l\head_ + For e = 0 To index + n = n\nx_ + Next + If n = l\tail_ Then n = Null ;Beyond the end of the list - not valid + + Else ;Negative index - count backward + n = l\tail_ + For e = 0 To index Step -1 + n = n\pv_ + Next + If n = l\head_ Then n = Null ;Before the start of the list - not valid + + EndIf + + Return n +End Function + +;Replace a value at the given position (added by MusicianKool) +Function ReplaceValueAtIndex(l.LList,index,value) + Local n.ListNode = ListNodeAtIndex(l,index) + If n <> Null Then n\Value = value:Else Return 0 +End Function + +;Remove and return a value at the given position (added by MusicianKool) +Function RemoveNodeAtIndex(l.LList,index) + Local n.ListNode = ListNodeAtIndex(l,index),tval + If n <> Null Then tval = n\Value:RemoveListNode(n):Return tval:Else Return 0 +End Function + +;Retrieve the first value from a list +Function ListFirst(l.LList) + If l\head_\nx_ <> l\tail_ Then Return l\head_\nx_\Value +End Function + +;Retrieve the last value from a list +Function ListLast(l.LList) + If l\tail_\pv_ <> l\head_ Then Return l\tail_\pv_\Value +End Function + +;Remove the first element from a list, and return its value +Function ListRemoveFirst(l.LList) + Local val + If l\head_\nx_ <> l\tail_ + val = l\head_\nx_\Value + RemoveListNode l\head_\nx_ + EndIf + Return val +End Function + +;Remove the last element from a list, and return its value +Function ListRemoveLast(l.LList) + Local val + If l\tail_\pv_ <> l\head_ + val = l\tail_\pv_\Value + RemoveListNode l\tail_\pv_ + EndIf + Return val +End Function + +;Insert a value into a list before the specified node, and return the new node +Function InsertBeforeNode.ListNode(Value, n.ListNode) + Local bef.ListNode = New ListNode + + bef\pv_ = n\pv_ + bef\nx_ = n + bef\Value = Value + + n\pv_ = bef + bef\pv_\nx_ = bef + + Return bef +End Function + +;Insert a value into a list after the specified node, and return then new node +Function InsertAfterNode.ListNode(Value, n.ListNode) + Local aft.ListNode = New ListNode + + aft\nx_ = n\nx_ + aft\pv_ = n + aft\Value = Value + + n\nx_ = aft + aft\nx_\pv_ = aft + + Return aft +End Function + +;Get an iterator object to use with a loop +;This function means that most programs won't have to think about deleting iterators manually +;(in general only a small, constant number will be created) +Function GetIterator.Iterator(l.LList) + Local i.Iterator + + If l = Null Then RuntimeError "Cannot create Iterator for Null" + + For i = Each Iterator ;See if there's an available iterator at the moment + If i\l_ = Null Then Exit + Next + + If i = Null Then i = New Iterator ;If there wasn't, create one + + i\l_ = l + i\cn_ = l\head_ + i\cni_ = -1 + i\Value = 0 ;No especial reason why this has to be anything, but meh + + Return i +End Function + +;Use as the argument to While to iterate over the members of a list +Function EachIn(i.Iterator) + + i\cn_ = i\cn_\nx_ + + If i\cn_ <> i\l_\tail_ ;Still items in the list + i\Value = i\cn_\Value + i\cni_ = i\cni_ + 1 + Return True + + Else + i\l_ = Null ;Disconnect from the list, having reached the end + i\cn_ = Null + i\cni_ = -1 + Return False + + EndIf +End Function + +;Remove from the containing list the element currently pointed to by an iterator +Function IteratorRemove(i.Iterator) + If (i\cn_ <> i\l_\head_) And (i\cn_ <> i\l_\tail_) + Local temp.ListNode = i\cn_ + + i\cn_ = i\cn_\pv_ + i\cni_ = i\cni_ - 1 + i\Value = 0 + + RemoveListNode temp + + Return True + Else + Return False + EndIf +End Function + +;Call this before breaking out of an EachIn loop, to disconnect the iterator from the list +Function IteratorBreak(i.Iterator) + i\l_ = Null + i\cn_ = Null + i\cni_ = -1 + i\Value = 0 +End Function + + +;~IDEal Editor Parameters: +;~F#5#A#10#18#2A#32#3E#47#4C#58#66#6F#78#8F#9B#A9#B7#BD#C5#CC +;~F#E3#E9#EF#F4#F9#103#10D#11B#12B#13F#152#163 +;~C#Blitz3D \ No newline at end of file diff --git a/samples/BlitzBasic/PObj.bb b/samples/BlitzBasic/PObj.bb new file mode 100644 index 00000000..2989f98e --- /dev/null +++ b/samples/BlitzBasic/PObj.bb @@ -0,0 +1,66 @@ + +Local i, start, result + +Local s.Sum3Obj = New Sum3Obj + +For i = 1 To 100000 + s = New Sum3Obj + result = Handle Before s + Delete s +Next + +start = MilliSecs() +For i = 1 To 1000000 + result = Sum3_(MakeSum3Obj(i, i, i)) +Next +start = MilliSecs() - start +Print start + +start = MilliSecs() +For i = 1 To 1000000 + result = Sum3(i, i, i) +Next +start = MilliSecs() - start +Print start + +WaitKey +End + + +Function Sum3(a, b, c) + Return a + b + c +End Function + + +Type Sum3Obj + Field isActive + Field a, b, c +End Type + +Function MakeSum3Obj(a, b, c) + Local s.Sum3Obj = Last Sum3Obj + If s\isActive Then s = New Sum3Obj + s\isActive = True + s\a = a + s\b = b + s\c = c + + Restore label + Read foo + + Return Handle(s) +End Function + +.label +Data (10 + 2), 12, 14 +: +Function Sum3_(a_) + Local a.Sum3Obj = Object.Sum3Obj a_ + Local return_ = a\a + a\b + a\c + Insert a Before First Sum3Obj :: a\isActive = False + Return return_ +End Function + + +;~IDEal Editor Parameters: +;~C#Blitz3D \ No newline at end of file