#194064 - 2009-05-30 05:07 PM
SteelKix
|
WvS
Fresh Scripter
Registered: 2009-05-30
Posts: 42
Loc: Netherlands
|
Hi Kix users,
For a while now, I've been working on a project that may interest you. I'm a 22 year old student from the Netherlands and I enjoy a bit of programming in my spare time. I'm especially interested in using new technologies related to creating programming languages. The project I'm working on is an implementation of Kix on the new Dynamic Language Runtime built by Microsoft. The DLR runs on top of the CLR and is part of the .net technology. I was introduced to Kix by my brother. Although Kix is not really impressive (language feature wise), I was pretty fascinated by the number of people that use it and the stuff built around it (like KiXforms). Having built a few useless languages, I decided to build one that may actually be useful to somebody.
The main advantage of SteelKix is the .net framework. SteelKix opens up the entire non generic .net framework, allowing much more functionality in the language.
Here is a list of some of the things that are possible in SteelKix:
• Multithreading • Using byte arrays • Sockets • Using .net events • Com event sinks • Using exception handling
A large difference with KiXtart is the way of executing scripts: SteelKix compiles your script before it runs. Your script is effectively translated to machine code at runtime by the .NET JIT compiler. The SteelKix compiler detects syntax errors before your script is executed.
I've designed SteelKix to be backward compatible. All of the kix scripts should also run on SteelKix.
At this point, the project is in an early stage. Most of the standard functions and some of the commands are not yet implemented. My idea is to implement the standard functions in SteelKix itself, since most things that are possible in C# are also possible in SteelKix. Macro's can also be defined within SteelKix.
Enough with the talk, I'll just post some examples where some of the new features are clearly visible. Please tell me what you think!
Solving the producer-consumer problem (multithreading)
Imports $t = system.threading ;new imports statement, importing namespaces defined by .net assemblies
imports $s = system
/* steelkix supports declaring with assignments (unlike vanilla kix) */
/* steelkix supports constructing clr objects */
global $fullSem = $t.Semaphore(10, 10),
$emptySem = $t.Semaphore(0, 10),
$buffer = $s.collections.Queue(),
$bufferMutex = $t.Mutex(),
$continue = 1
/* steelkix supports function to delegate conversion */
dim $producerThread = $t.Thread($t.ThreadStart(AddressOf Producer)),
$consumerThread = $t.Thread($t.ThreadStart(AddressOf Consumer))
$producerThread.Start
$consumerThread.Start
$producerThread.Join
$consumerThread.Join
"done"
/* produce some crap (fibonacci), simulate hard working thread */
function Producer()
dim $fibOne = 1, $fibTwo = 2
dim $rand = $s.random()
dim $tmp
dim $proberen
dim $verhogen
while $fibTwo < 100000
$proberen = $fullSem.WaitOne
$tmp = $fibTwo
$fibTwo = $fibOne + $fibTwo
$fibOne = $tmp
$proberen = $bufferMutex.WaitOne
$buffer.Enqueue($fibTwo)
$bufferMutex.ReleaseMutex
$verhogen = $emptySem.Release
SLEEP $rand.Next(0, 5)
loop
$continue = 0
endfunction
/* consume results from producer (print them) */
function Consumer()
dim $proberen
dim $verhogen
while $continue
if not $emptySem.WaitOne(5000)
exit 0
endif
$proberen = $bufferMutex.WaitOne
? $buffer.Dequeue()
$bufferMutex.ReleaseMutex
$verhogen = $fullSem.Release
loop
endfunction
Creating a simple TCP server
imports $system = system
imports $net = system.net
imports $sockets = system.net.sockets
imports $threading = system.threading
global $continue = 1
; new addressof operator
dim $listenThread = $threading.Thread($threading.ThreadStart(AddressOf Listen))
global $listenSocket
dim $line = ""
"Starting listen thread"
$listenThread.Start
while $line <> "exit"
gets $line
loop
$continue = 0
? "Closing.."
$listenSocket.Close
function Listen
dim $port = 1050
$listenSocket = $sockets.socket($sockets.addressfamily.internetwork,
$sockets.sockettype.stream,
$sockets.protocoltype.tcp)
;listen on port 1050
$listenSocket.Bind($net.IPEndPoint($net.IPAddress.Any, $port))
$listenSocket.Listen(10)
? "Started listening on port $port"
while $continue
; new try/catch block
try
dim $client = $listenSocket.Accept
? "Accepted client: " + $client.EndPoint.tostring
dim $thread = $threading.Thread($threading.ParameterizedThreadStart(AddressOf HandleClient))
$thread.Start($client)
endtry
catch
break
endcatch
loop
$listenSocket.close
endfunction
function HandleClient($client)
;build byte array
dim $buffer = $system.Array.CreateInstance($system.Type.GetType("System.Byte"), 1024)
while $continue
dim $bytesRead = $client.Receive($buffer)
? "Received $bytesRead! woot!"
if $bytesRead > 0
$client.Send($buffer, $bytesRead, $sockets.SocketFlags.None)
else
break
endif
loop
endfunction
Creating a WPF application
reference("system.xml")
; reference .net assemblies
referenceExact("PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
referenceExact("PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
imports $markup = system.windows.markup
imports $win = system.windows
imports $io = system.io
imports $xml = system.xml
; create a cube that can be rotated
dim $xaml = '<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SteelKix XAML rotating cube biatch!" Height="300" Width="300"
>
<DockPanel>
<ScrollBar Name="hscroll"
DockPanel.Dock="Bottom"
Orientation="Horizontal"
Minimum="-180" Maximum="180"
LargeChange="10" SmallChange="1" Value="0" />
<ScrollBar Name="vscroll"
DockPanel.Dock="Right"
Orientation="Vertical"
Minimum="-180" Maximum="180"
LargeChange="10" SmallChange="1" Value="0" />
<Viewport3D Margin="4,4,4,4">
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup>
<!-- Lights -->
<AmbientLight Color="Gray" />
<DirectionalLight Color="Gray"
Direction="1,-2,-3" />
<DirectionalLight Color="Gray"
Direction="-1,2,3" />
<GeometryModel3D>
<GeometryModel3D.Geometry>
<!-- Cube -->
<MeshGeometry3D
Positions="
-1,-1,-1 1,-1,-1 1,-1, 1 -1,-1, 1
-1,-1, 1 1,-1, 1 1, 1, 1 -1, 1, 1
1,-1, 1 1,-1,-1 1, 1,-1 1, 1, 1
1, 1, 1 1, 1,-1 -1, 1,-1 -1, 1, 1
-1,-1, 1 -1, 1, 1 -1, 1,-1
-1,-1,-1
-1,-1,-1 -1, 1,-1 1, 1,-1 1,-1,-1
"
TriangleIndices="
0 1 2 2 3 0
4 5 6 6 7 4
8 9 10 10 11 8
12 13 14 14 15 12
16 17 18 18 19 16
20 21 22 22 23 20
" />
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial Brush="Red" />
</GeometryModel3D.Material>
</GeometryModel3D>
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
<Viewport3D.Camera>
<PerspectiveCamera
Position = "2, 4, 6"
LookDirection = "-1, -2, -3"
UpDirection = "0, 1, 0"
FieldOfView = "60">
<PerspectiveCamera.Transform>
<Transform3DGroup>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D
Axis="0 1 0"
Angle="{Binding ElementName=hscroll, Path=Value}" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D
Axis="1 0 0"
Angle="{Binding ElementName=vscroll, Path=Value}" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</Transform3DGroup>
</PerspectiveCamera.Transform>
</PerspectiveCamera>
</Viewport3D.Camera>
</Viewport3D>
</DockPanel>
</Window>'
dim $app = $win.application()
dim $xmlReader = $xml.XmlReader.Create($io.StringReader($xaml)),
$window = $markup.XamlReader.Load($xmlReader)
$app.Run($window)
Creating a winforms application
reference("system.windows.forms") ;referenceExact is better (prevent dll hell). I'm being lazy here.
reference("system.drawing")
reference("system.data")
dim $explicit = setoption("explicit", "on")
imports $system = system
imports $forms = system.windows.forms
imports $drawing = system.drawing
imports $data = system.data
global $form = $forms.form()
global $grid = $forms.dataGridView()
global $btnClose = $forms.button()
$form.Size = $drawing.size(800, 600)
$form.Load += $system.eventhandler(addressOf Form_load)
$grid.location = $drawing.point(12, 21)
$grid.size = $drawing.size(758, 451)
$grid.anchor = $forms.anchorStyles.Top | $forms.anchorStyles.Left | $forms.anchorStyles.Bottom | $forms.anchorStyles.Right
$btnClose.location = $drawing.point(678, 500)
$btnClose.size = $drawing.size(92, 23)
$btnClose.Text = "Close"
$btnClose.Click += $system.eventhandler(AddressOf btnClose_Click)
$form.Text = "SteelKix WF example"
$form.Controls.add($grid)
$form.controls.add($btnClose)
$forms.Application.enableVisualStyles
$forms.Application.Run($form);
function Form_Load($sender, $e)
;fill the grid up with some xml
dim $dataSet = $data.dataset()
dim $reader = $system.io.stringreader("<?xml version='1.0' standalone='yes'?>
<NewDataSet>
<Product>
<Name>Bread</Name>
<Price>$$4</Price>
<Stock>20</Stock>
</Product>
<Product>
<Name>Milk</Name>
<Price>$$2</Price>
<Stock>54</Stock>
</Product>
<Product>
<Name>Butter</Name>
<Price>$$1</Price>
<Stock>13</Stock>
</Product>
</NewDataSet>")
$dataset.ReadXml($reader)
$grid.datasource = $dataset.tables[0].defaultview
endfunction
function btnClose_Click($sender, $e)
$form.close
endfunction
Using COM event sinks
imports $system = system
dim $xmlHttp = CreateObject("Msxml2.DOMDocument.3.0")
$xmlHttp.onreadystatechange += addressOf XmlHttp_readyStateChange
$xmlHttp.Load("http://posc.org/ebiz/blmSamples/blm3160-3.xml")
function XmlHttp_readyStateChange
"test"
endfunction
Using LINQ libraries
reference("System.Core") ;load up linq libraries
imports $linq = system.linq.expressions.expression
imports $s = system
/* build the parameters used for the lambda */
dim $x = $linq.parameter($s.Type.GetType("System.Int32"), "x"),
$y = $linq.parameter($s.Type.GetType("System.Int32"), "y")
/* build the lambda (x+y equivalent) */
dim $expr = $linq.Lambda(
$linq.Add(
$x,
$y
),
$x, $y
)
/* compile into .net delegate */
dim $delegate = $expr.Compile
/* invoke the delegate */
$delegate(1, 2)
Default parameter values
imports $debug = System.Diagnostics.Debug
$debug.Assert(assert(foo(1), 1, 5, 6))
$debug.Assert(assert(foo(1, 2), 1, 2, 6)) ; 1 2 6
$debug.Assert(assert(foo(1, , 3), 1, 5, 3)) ; 1 5 3
$debug.Assert(assert(foo(1, ,), 1, 5, 6)) ; 1 5 6
$debug.Assert(assert(foo(1,2,), 1, 2, 6)) ; 1 2 6
"All success"
;optional parameters with default values
function foo($array, optional $b = 5, optional $c = 6)
$foo = [$array, $b, $c]
endfunction
function assert($ret, $v1, $v2, $v3)
$assert = ($ret[0] = $v1 and $ret[1] = $v2 and $ret[2] = $v3)
endfunction
Edited by WvS (2009-05-30 05:10 PM)
|
Top
|
|
|
|
#194068 - 2009-05-31 04:32 AM
Re: SteelKix
[Re: Shawn]
|
Benny69
Moderator
Registered: 2003-10-29
Posts: 1036
Loc: Lincoln, Ne
|
OK, you have our attention, I hope this is not a carrot on a stick, please give us updates and many of them.
|
Top
|
|
|
|
#194072 - 2009-05-31 02:32 PM
Re: SteelKix
[Re: It_took_my_meds]
|
WvS
Fresh Scripter
Registered: 2009-05-30
Posts: 42
Loc: Netherlands
|
It is possible to create a shell for visual studio. Syntax highlighting would then be possible, yes. I'm not to sure about intellisense. There is some more info on this stuff here : http://msdn.microsoft.com/nl-nl/vsx/cc677257(en-us).aspx
|
Top
|
|
|
|
#194692 - 2009-07-12 04:58 PM
Re: SteelKix
[Re: It_took_my_meds]
|
WvS
Fresh Scripter
Registered: 2009-05-30
Posts: 42
Loc: Netherlands
|
Sorry for the delay. Here it is: http://steelkix.codeplex.com/. Includes full source code. Slighty modified scripts from first post are also included.
I really hope this project is useful for somebody, response hasn't really been overwhelming.
|
Top
|
|
|
|
Moderator: Glenn Barnas, NTDOC, Arend_, Jochen, Radimus, Allen, ShaneEP, Ruud van Velsen, Mart
|
0 registered
and 718 anonymous users online.
|
|
|