├── .gitignore ├── CompilerTest ├── CompilerTest.csproj ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── app.config ├── Documentation ├── Documentation.csproj ├── DocumentationGenerator.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Resources │ ├── Appendix.txt │ ├── AppendixFR.txt │ ├── Manual.txt │ ├── ManualDE.txt │ ├── ManualES.txt │ ├── ManualFR.txt │ ├── ManualRU.txt │ └── Styles.txt ├── SmallBasicEV3Extension.de.XML ├── SmallBasicEV3Extension.es.XML ├── SmallBasicEV3Extension.fr.XML ├── SmallBasicEV3Extension.pl.XML ├── SmallBasicEV3Extension.ru.XML ├── app.config ├── ev3basic_handbuch.html ├── ev3basic_manual.html ├── ev3basic_manual_es.html ├── ev3basic_manual_ru.html ├── ev3basic_manuel.html └── gpl-3.0.txt ├── EV3Basic.sln ├── EV3BasicCompiler ├── CompileException.cs ├── Compiler.cs ├── EV3BasicCompiler.csproj ├── Expression.cs ├── FunctionDefinition.cs ├── LibraryEntry.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Resources │ ├── Assert.txt │ ├── Buttons.txt │ ├── Byte.txt │ ├── EV3.txt │ ├── EV3File.txt │ ├── LCD.txt │ ├── Mailbox.txt │ ├── Math.txt │ ├── Motor.txt │ ├── NativeCode.txt │ ├── Program.txt │ ├── Sensor.txt │ ├── Speaker.txt │ ├── Text.txt │ ├── Thread.txt │ ├── Vector.txt │ └── runtimelibrary.txt └── Scanner.cs ├── EV3BasicInstaller └── EV3BasicInstaller.vdproj ├── EV3Communication ├── BinaryBuffer.cs ├── ByteCodeBuffer.cs ├── ConnectionFinder.cs ├── ConnectionTypeDialog.xaml ├── ConnectionTypeDialog.xaml.cs ├── EV3Communication.csproj ├── EV3Connection.cs ├── EV3ConnectionBluetooth.cs ├── EV3ConnectionUSB.cs ├── EV3ConnectionWiFi.cs ├── EV3RemoteControler.cs ├── EV3Watchdog.lms ├── EV3Watchdog.rbf ├── IPAddressDialog.xaml ├── IPAddressDialog.xaml.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx └── Resources │ ├── NativeCode.txt │ └── WatchDog.txt ├── EV3Explorer ├── App.xaml ├── App.xaml.cs ├── DirectoryEntry.cs ├── EV3Explorer.csproj ├── ExplorerSettings.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── QuestionBox.xaml ├── QuestionBox.xaml.cs └── app.config ├── Examples ├── ActionLoop.sb ├── Battery.sb ├── BlockingOperations.sb ├── BrickBench.sb ├── ButtonsAndMotors.sb ├── Byte.sb ├── ClickTest.sb ├── Concurrency.sb ├── DaisyChain.sb ├── File.sb ├── Function.sb ├── GraphicsAndSounds.sb ├── GraphicsAndSounds │ ├── emerald.rsf │ └── yamyam.rgf ├── HelloWorld.sb ├── I2CRegisters.sb ├── MailboxReceive.sb ├── MailboxSend.sb ├── Melody.sb ├── MotorCount.sb ├── MotorInvert.sb ├── MotorSteer.sb ├── MotorSynchronize.sb ├── MovingCircle.sb ├── Recursion.sb ├── SensorInfo.sb ├── SensorReading.sb ├── Threads.sb ├── TimeMeasurement.sb ├── TouchSensorTest.sb ├── TowersOfHanoi.sb ├── TwoMotorMovement.sb └── VectorDemo.sb ├── LMSAssembler ├── Assembler.cs ├── AssemblerException.cs ├── DataArea.cs ├── DataReader.cs ├── DataType.cs ├── DataWriter.cs ├── LMSAssembler.csproj ├── LMSObject.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Resources │ └── bytecodelist.txt └── VMCommand.cs ├── README.md ├── SmallBasicEV3Extension ├── Assert.cs ├── Buttons.cs ├── Byte.cs ├── EV3.cs ├── EV3File.cs ├── F.cs ├── LCD.cs ├── Mailbox.cs ├── Motor.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Sensor.cs ├── SmallBasicEV3Extension.csproj ├── Speaker.cs ├── Thread.cs ├── Vector.cs └── externals │ ├── SmallBasicLibrary - V1.1.dll │ └── SmallBasicLibrary.dll ├── native ├── nativecode └── nativecode.c └── testsuite ├── assemblertest.lms ├── benchmarkresults.txt ├── ev3features ├── CPUConsumption.sb ├── ConcurrentWaits.sb ├── FileAccess.sb ├── I2CMultiByte.sb ├── IC2SendPulse.sb ├── NativeCode.sb ├── TableLookup.sb └── UARTSend.sb ├── floatparameter.lms ├── languagefeatures ├── ArrayTest.sb ├── ConcurrentThreads.sb ├── LargeMemory.sb ├── Locking.sb ├── ManyThreads.sb ├── MathTest.sb ├── MultiThreading.sb ├── NestedExpressions.sb ├── OperatorPrecedence.sb ├── ProgramConstructs.sb ├── RecursionTest.sb ├── SpaghettiCode.sb └── TextTest.sb ├── subcallalias.lms ├── threads.lms └── variableparameter.lms /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | Examples.zip 9 | 10 | # Build results 11 | [Dd]ebug/ 12 | [Dd]ebugPublic/ 13 | [Rr]elease/ 14 | [Rr]eleases/ 15 | x64/ 16 | x86/ 17 | build/ 18 | bld/ 19 | [Bb]in/ 20 | [Oo]bj/ 21 | 22 | # Roslyn cache directories 23 | *.ide/ 24 | 25 | # MSTest test Results 26 | [Tt]est[Rr]esult*/ 27 | [Bb]uild[Ll]og.* 28 | 29 | #NUNIT 30 | *.VisualState.xml 31 | TestResult.xml 32 | 33 | # Build Results of an ATL Project 34 | [Dd]ebugPS/ 35 | [Rr]eleasePS/ 36 | dlldata.c 37 | 38 | *_i.c 39 | *_p.c 40 | *_i.h 41 | *.ilk 42 | *.meta 43 | *.obj 44 | *.pch 45 | *.pdb 46 | *.pgc 47 | *.pgd 48 | *.rsp 49 | *.sbr 50 | *.tlb 51 | *.tli 52 | *.tlh 53 | *.tmp 54 | *.tmp_proj 55 | *.log 56 | *.vspscc 57 | *.vssscc 58 | .builds 59 | *.pidb 60 | *.svclog 61 | *.scc 62 | 63 | # Chutzpah Test files 64 | _Chutzpah* 65 | 66 | # Visual C++ cache files 67 | ipch/ 68 | *.aps 69 | *.ncb 70 | *.opensdf 71 | *.sdf 72 | *.cachefile 73 | 74 | # Visual Studio profiler 75 | *.psess 76 | *.vsp 77 | *.vspx 78 | 79 | # TFS 2012 Local Workspace 80 | $tf/ 81 | 82 | # Guidance Automation Toolkit 83 | *.gpState 84 | 85 | # ReSharper is a .NET coding add-in 86 | _ReSharper*/ 87 | *.[Rr]e[Ss]harper 88 | *.DotSettings.user 89 | 90 | # JustCode is a .NET coding addin-in 91 | .JustCode 92 | 93 | # TeamCity is a build add-in 94 | _TeamCity* 95 | 96 | # DotCover is a Code Coverage Tool 97 | *.dotCover 98 | 99 | # NCrunch 100 | _NCrunch_* 101 | .*crunch*.local.xml 102 | 103 | # MightyMoose 104 | *.mm.* 105 | AutoTest.Net/ 106 | 107 | # Web workbench (sass) 108 | .sass-cache/ 109 | 110 | # Installshield output folder 111 | [Ee]xpress/ 112 | 113 | # DocProject is a documentation generator add-in 114 | DocProject/buildhelp/ 115 | DocProject/Help/*.HxT 116 | DocProject/Help/*.HxC 117 | DocProject/Help/*.hhc 118 | DocProject/Help/*.hhk 119 | DocProject/Help/*.hhp 120 | DocProject/Help/Html2 121 | DocProject/Help/html 122 | 123 | # Click-Once directory 124 | publish/ 125 | 126 | # Publish Web Output 127 | *.[Pp]ublish.xml 128 | *.azurePubxml 129 | # TODO: Comment the next line if you want to checkin your web deploy settings 130 | # but database connection strings (with potential passwords) will be unencrypted 131 | *.pubxml 132 | *.publishproj 133 | 134 | # NuGet Packages 135 | *.nupkg 136 | # The packages folder can be ignored because of Package Restore 137 | **/packages/* 138 | # except build/, which is used as an MSBuild target. 139 | !**/packages/build/ 140 | # If using the old MSBuild-Integrated Package Restore, uncomment this: 141 | #!**/packages/repositories.config 142 | 143 | # Windows Azure Build Output 144 | csx/ 145 | *.build.csdef 146 | 147 | # Windows Store app package directory 148 | AppPackages/ 149 | 150 | # Others 151 | sql/ 152 | *.Cache 153 | ClientBin/ 154 | [Ss]tyle[Cc]op.* 155 | ~$* 156 | *~ 157 | *.dbmdl 158 | *.dbproj.schemaview 159 | *.pfx 160 | *.publishsettings 161 | node_modules/ 162 | 163 | # RIA/Silverlight projects 164 | Generated_Code/ 165 | 166 | # Backup & report files from converting an old project file 167 | # to a newer Visual Studio version. Backup files are not needed, 168 | # because we have git ;-) 169 | _UpgradeReport_Files/ 170 | Backup*/ 171 | UpgradeLog*.XML 172 | UpgradeLog*.htm 173 | 174 | # SQL Server files 175 | *.mdf 176 | *.ldf 177 | 178 | # Business Intelligence projects 179 | *.rdl.data 180 | *.bim.layout 181 | *.bim_*.settings 182 | 183 | # Microsoft Fakes 184 | FakesAssemblies/ 185 | -------------------------------------------------------------------------------- /CompilerTest/CompilerTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {7FCDF143-6E28-4D5E-ADFD-44C0A30325E3} 8 | Exe 9 | Properties 10 | CompilerTest 11 | CompilerTest 12 | v4.5 13 | 512 14 | false 15 | publish\ 16 | true 17 | Disk 18 | false 19 | Foreground 20 | 7 21 | Days 22 | false 23 | false 24 | true 25 | 0 26 | 1.0.0.%2a 27 | false 28 | true 29 | 30 | 31 | 32 | 33 | AnyCPU 34 | true 35 | full 36 | false 37 | bin\Debug\ 38 | DEBUG;TRACE 39 | prompt 40 | 4 41 | false 42 | 43 | 44 | AnyCPU 45 | pdbonly 46 | true 47 | bin\Release\ 48 | TRACE 49 | prompt 50 | 4 51 | false 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | False 68 | .NET Framework 3.5 SP1 Client Profile 69 | false 70 | 71 | 72 | False 73 | .NET Framework 3.5 SP1 74 | true 75 | 76 | 77 | 78 | 79 | {41e8f7a9-d228-4323-bd0d-f479ef81072c} 80 | EV3BasicCompiler 81 | 82 | 83 | {db6e87ad-6cb4-401a-925b-7e40f7cbf042} 84 | LMSAssembler 85 | 86 | 87 | 88 | 89 | 90 | 91 | 98 | -------------------------------------------------------------------------------- /CompilerTest/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | using EV3BasicCompiler; 7 | using LMSAssembler; 8 | using System.Net.Sockets; 9 | using System.Net; 10 | 11 | namespace Test 12 | { 13 | class Program 14 | { 15 | static void Main(string[] args) 16 | { 17 | // TestWiFiReceiveBroadcast(); 18 | // TestWiFi(); 19 | TestCompile(); 20 | TestAssemble(); 21 | // TestDisassemble(); 22 | } 23 | 24 | static void TestDisassemble() 25 | { 26 | Assembler a = new Assembler(); 27 | 28 | String f = "C:/temp/Program.rbf"; 29 | FileStream fs = new FileStream(f, FileMode.Open, FileAccess.Read); 30 | 31 | a.Disassemble(fs, Console.Out); 32 | 33 | Console.ReadKey(); 34 | } 35 | 36 | static void TestCompile() 37 | { 38 | String f = "C:/Users/Reinhard/Documents/GitHub/EV3Basic/Examples/HelloWorld.sb"; 39 | // String f = "C:/Users/Reinhard/Desktop/Gripper_Rolf.sb"; 40 | FileStream fs = new FileStream(f, FileMode.Open, FileAccess.Read); 41 | FileStream ofs = new FileStream("c:/temp/compiledbasic.lms", FileMode.Create, FileAccess.Write); 42 | 43 | List errors = new List(); 44 | 45 | try 46 | { 47 | Compiler c = new Compiler(); 48 | c.Compile(fs, ofs, errors); 49 | 50 | ofs.Close(); 51 | fs.Close(); 52 | 53 | if (errors.Count > 0) 54 | { 55 | foreach (String s in errors) 56 | { 57 | Console.WriteLine(s); 58 | } 59 | Console.ReadKey(); 60 | } 61 | 62 | } 63 | catch (Exception e) 64 | { 65 | ofs.Close(); 66 | fs.Close(); 67 | Console.WriteLine("Compiler error: "+e.Message); 68 | Console.WriteLine(e.StackTrace); 69 | Console.ReadKey(); 70 | } 71 | } 72 | 73 | static void TestAssemble() 74 | { 75 | Assembler a = new Assembler(); 76 | 77 | String f = "C:/temp/compiledbasic.lms"; 78 | FileStream fs = new FileStream(f, FileMode.Open, FileAccess.Read); 79 | 80 | FileStream ofs = new FileStream("c:/temp/compiledbasic.rbf", FileMode.Create, FileAccess.Write); 81 | 82 | List errors = new List(); 83 | 84 | a.Assemble(fs, ofs, errors); 85 | 86 | fs.Close(); 87 | ofs.Close(); 88 | 89 | if (errors.Count>0) 90 | { 91 | foreach (String s in errors) 92 | { Console.WriteLine(s); 93 | } 94 | Console.ReadKey(); 95 | } 96 | } 97 | 98 | 99 | static void TestWiFi() 100 | { 101 | Console.WriteLine("Connecting..."); 102 | TcpClient c = new TcpClient("10.0.0.140", 5555); 103 | Console.WriteLine("Connected!"); 104 | NetworkStream s = c.GetStream(); 105 | Console.WriteLine("Sending data..."); 106 | byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes("GET /target?sn=0016533F0C1E VMTP1.0\r\nProtocol: EV3\r\n\r\n"); 107 | // byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes("X"); 108 | s.Write(data, 0, data.Length); 109 | 110 | for (; ; ) 111 | { 112 | int b = s.ReadByte(); 113 | if (b < 0) break; 114 | Console.WriteLine(b); 115 | } 116 | 117 | s.Close(); 118 | c.Close(); 119 | } 120 | 121 | static void TestWiFiReceiveBroadcast() 122 | { 123 | Console.WriteLine("Opening receiving UDP port..."); 124 | UdpClient c = new UdpClient(3015); 125 | 126 | IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); 127 | 128 | Console.WriteLine("Receiving incomming packets..."); 129 | for (;;) 130 | { 131 | byte[] data = c.Receive(ref RemoteIpEndPoint); 132 | Console.WriteLine("Received: "+data.Length+ "bytes"); 133 | Console.WriteLine(System.Text.UTF8Encoding.UTF8.GetString(data)); 134 | } 135 | 136 | // c.Close(); 137 | } 138 | 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /CompilerTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Compiler")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Compiler")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("4340a521-95f1-4bc2-aa43-e4e7dd9ebc39")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /CompilerTest/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Documentation/Documentation.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {A2EE623F-44B6-4853-B3EB-27836A918F5D} 8 | Exe 9 | Properties 10 | Documentation 11 | Documentation 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | false 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | false 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | True 51 | True 52 | Resources.resx 53 | 54 | 55 | 56 | 57 | ResXFileCodeGenerator 58 | Resources.Designer.cs 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | Designer 79 | 80 | 81 | 82 | 83 | 84 | Designer 85 | 86 | 87 | 88 | 89 | 90 | 97 | -------------------------------------------------------------------------------- /Documentation/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Documentation")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Documentation")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("c98c4bcc-56ba-4820-97c3-0f0766dd38e2")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Documentation/Resources/AppendixFR.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/c0pperdragon/EV3Basic/762f3638324f66a0ee6d4fb0f9e095683b742e4c/Documentation/Resources/AppendixFR.txt -------------------------------------------------------------------------------- /Documentation/Resources/ManualDE.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/c0pperdragon/EV3Basic/762f3638324f66a0ee6d4fb0f9e095683b742e4c/Documentation/Resources/ManualDE.txt -------------------------------------------------------------------------------- /Documentation/Resources/ManualES.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/c0pperdragon/EV3Basic/762f3638324f66a0ee6d4fb0f9e095683b742e4c/Documentation/Resources/ManualES.txt -------------------------------------------------------------------------------- /Documentation/Resources/ManualRU.txt: -------------------------------------------------------------------------------- 1 | 

Справочник по командам EV3 Бейсик

2 |

3 | Перевод: Андрей Степанов, «Карандаш и Самоделкин» 4 |

5 | -------------------------------------------------------------------------------- /Documentation/Resources/Styles.txt: -------------------------------------------------------------------------------- 1 | 94 | -------------------------------------------------------------------------------- /Documentation/SmallBasicEV3Extension.es.XML: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/c0pperdragon/EV3Basic/762f3638324f66a0ee6d4fb0f9e095683b742e4c/Documentation/SmallBasicEV3Extension.es.XML -------------------------------------------------------------------------------- /Documentation/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /EV3Basic.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5E2ACF19-CD12-438F-BF02-5EE25E4BFDD9}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CompilerTest", "CompilerTest\CompilerTest.csproj", "{7FCDF143-6E28-4D5E-ADFD-44C0A30325E3}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LMSAssembler", "LMSAssembler\LMSAssembler.csproj", "{DB6E87AD-6CB4-401A-925B-7E40F7CBF042}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EV3Explorer", "EV3Explorer\EV3Explorer.csproj", "{3DAB387B-F044-4BEA-9511-EE6C71164830}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EV3Communication", "EV3Communication\EV3Communication.csproj", "{C3C8582B-F715-41F9-A565-14C6918A0105}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmallBasicEV3Extension", "SmallBasicEV3Extension\SmallBasicEV3Extension.csproj", "{1AA9B6CA-3833-4012-89C9-5628BEBA1657}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EV3BasicCompiler", "EV3BasicCompiler\EV3BasicCompiler.csproj", "{41E8F7A9-D228-4323-BD0D-F479EF81072C}" 19 | EndProject 20 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Documentation", "Documentation\Documentation.csproj", "{A2EE623F-44B6-4853-B3EB-27836A918F5D}" 21 | EndProject 22 | Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "EV3BasicInstaller", "EV3BasicInstaller\EV3BasicInstaller.vdproj", "{77F4EC78-B79A-42C6-ABDE-15C1AE2D48B1}" 23 | EndProject 24 | Global 25 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 26 | Debug|Any CPU = Debug|Any CPU 27 | Release|Any CPU = Release|Any CPU 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {7FCDF143-6E28-4D5E-ADFD-44C0A30325E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {7FCDF143-6E28-4D5E-ADFD-44C0A30325E3}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {7FCDF143-6E28-4D5E-ADFD-44C0A30325E3}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {7FCDF143-6E28-4D5E-ADFD-44C0A30325E3}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {DB6E87AD-6CB4-401A-925B-7E40F7CBF042}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {DB6E87AD-6CB4-401A-925B-7E40F7CBF042}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {DB6E87AD-6CB4-401A-925B-7E40F7CBF042}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {DB6E87AD-6CB4-401A-925B-7E40F7CBF042}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {3DAB387B-F044-4BEA-9511-EE6C71164830}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {3DAB387B-F044-4BEA-9511-EE6C71164830}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {3DAB387B-F044-4BEA-9511-EE6C71164830}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {3DAB387B-F044-4BEA-9511-EE6C71164830}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {C3C8582B-F715-41F9-A565-14C6918A0105}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {C3C8582B-F715-41F9-A565-14C6918A0105}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {C3C8582B-F715-41F9-A565-14C6918A0105}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {C3C8582B-F715-41F9-A565-14C6918A0105}.Release|Any CPU.Build.0 = Release|Any CPU 46 | {1AA9B6CA-3833-4012-89C9-5628BEBA1657}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {1AA9B6CA-3833-4012-89C9-5628BEBA1657}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {1AA9B6CA-3833-4012-89C9-5628BEBA1657}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {1AA9B6CA-3833-4012-89C9-5628BEBA1657}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {41E8F7A9-D228-4323-BD0D-F479EF81072C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {41E8F7A9-D228-4323-BD0D-F479EF81072C}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {41E8F7A9-D228-4323-BD0D-F479EF81072C}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {41E8F7A9-D228-4323-BD0D-F479EF81072C}.Release|Any CPU.Build.0 = Release|Any CPU 54 | {A2EE623F-44B6-4853-B3EB-27836A918F5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 55 | {A2EE623F-44B6-4853-B3EB-27836A918F5D}.Debug|Any CPU.Build.0 = Debug|Any CPU 56 | {A2EE623F-44B6-4853-B3EB-27836A918F5D}.Release|Any CPU.ActiveCfg = Release|Any CPU 57 | {A2EE623F-44B6-4853-B3EB-27836A918F5D}.Release|Any CPU.Build.0 = Release|Any CPU 58 | {77F4EC78-B79A-42C6-ABDE-15C1AE2D48B1}.Debug|Any CPU.ActiveCfg = Debug 59 | {77F4EC78-B79A-42C6-ABDE-15C1AE2D48B1}.Release|Any CPU.ActiveCfg = Release 60 | {77F4EC78-B79A-42C6-ABDE-15C1AE2D48B1}.Release|Any CPU.Build.0 = Release 61 | EndGlobalSection 62 | GlobalSection(SolutionProperties) = preSolution 63 | HideSolutionNode = FALSE 64 | EndGlobalSection 65 | EndGlobal 66 | -------------------------------------------------------------------------------- /EV3BasicCompiler/CompileException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace EV3BasicCompiler 7 | { 8 | class CompileException: System.Exception 9 | { 10 | public CompileException(String message) : base(message) 11 | { 12 | } 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /EV3BasicCompiler/EV3BasicCompiler.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {41E8F7A9-D228-4323-BD0D-F479EF81072C} 8 | Library 9 | Properties 10 | EV3BasicCompiler 11 | EV3BasicCompiler 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | false 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | True 52 | True 53 | Resources.resx 54 | 55 | 56 | 57 | 58 | 59 | ResXFileCodeGenerator 60 | Resources.Designer.cs 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 122 | -------------------------------------------------------------------------------- /EV3BasicCompiler/LibraryEntry.cs: -------------------------------------------------------------------------------- 1 | /* EV3-Basic: A basic compiler to target the Lego EV3 brick 2 | Copyright (C) 2015 Reinhard Grafl 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Text; 21 | 22 | namespace EV3BasicCompiler 23 | { 24 | class LibraryEntry 25 | { 26 | public readonly bool inline; 27 | 28 | public readonly ExpressionType returnType; 29 | public readonly ExpressionType[] paramTypes; 30 | 31 | public readonly String[] references; 32 | 33 | public readonly String programCode; 34 | 35 | public LibraryEntry(bool inline, String[] descriptor_and_references, String code) 36 | { 37 | this.inline = inline; 38 | String descriptor = descriptor_and_references[0]; 39 | returnType = decodeType(descriptor[descriptor.Length-1]); 40 | 41 | paramTypes = new ExpressionType[descriptor.Length - 1]; 42 | for (int i = 0; i < paramTypes.Length; i++) 43 | { 44 | paramTypes[i] = decodeType(descriptor[i]); 45 | } 46 | 47 | references = new String[descriptor_and_references.Length - 1]; 48 | for (int i = 0; i < references.Length; i++) 49 | { 50 | references[i] = descriptor_and_references[1 + i]; 51 | } 52 | 53 | // for inlining code, trim away "{" and "}" 54 | if (inline) 55 | { 56 | int startbrace = code.IndexOf('{'); 57 | int endbrace = code.IndexOf('}'); 58 | code = code.Substring(startbrace + 1, endbrace - startbrace - 2).Trim(); 59 | } 60 | programCode = code; 61 | } 62 | 63 | private ExpressionType decodeType(char c) 64 | { 65 | switch (c) 66 | { case 'F': return ExpressionType.Number; 67 | case 'S': return ExpressionType.Text; 68 | case 'A': return ExpressionType.NumberArray; 69 | case 'X': return ExpressionType.TextArray; 70 | case 'V': return ExpressionType.Void; 71 | default: throw new Exception("Can not read runtime library"); 72 | } 73 | } 74 | 75 | public override string ToString() 76 | { 77 | StringBuilder s = new StringBuilder(); 78 | for (int i = 0; i < paramTypes.Length; i++) 79 | { 80 | s.Append(paramTypes[i]); 81 | s.Append(" "); 82 | } 83 | s.Append("-> "); 84 | s.Append(returnType); 85 | return s.ToString(); 86 | } 87 | 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /EV3BasicCompiler/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("BasicCompiler")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("BasicCompiler")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("4fab17b8-60db-4697-9f52-66af941429fc")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /EV3BasicCompiler/Resources/Assert.txt: -------------------------------------------------------------------------------- 1 | // -------------------------------------- EXTENSION MODULE: ASSERT ----------------------------------- 2 | 3 | subcall ASSERT.FAILED // SV TEXT.GETSUBTEXT TEXT.GETSUBTEXTTOEND 4 | { 5 | IN_S message 252 6 | 7 | UI_DRAW CLEAN 8 | UI_DRAW SELECT_FONT 1 9 | UI_DRAW TEXT 1 0 16 'ASSERT FAILED' 10 | 11 | DATA16 y 12 | MOVE16_16 32 y 13 | 14 | linesloop: 15 | DATA16 len 16 | STRINGS GET_SIZE message len 17 | JR_LTEQ16 len 22 lastline 18 | 19 | DATAS oneline 252 20 | CALL TEXT.GETSUBTEXT message 1.0 22.0 oneline 21 | UI_DRAW TEXT 1 0 y oneline 22 | ADD16 y 12 y 23 | 24 | CALL TEXT.GETSUBTEXTTOEND message 23.0 message 25 | JR linesloop 26 | 27 | lastline: 28 | UI_DRAW TEXT 1 0 y message 29 | UI_DRAW UPDATE 30 | } 31 | 32 | subcall ASSERT.EQUAL // SSSV ASSERT.FAILED TEXT.APPEND 33 | { 34 | IN_S a 252 35 | IN_S b 252 36 | IN_S message 252 37 | 38 | DATA8 flag 39 | 40 | STRINGS COMPARE a b flag 41 | JR_NEQ8 flag 0 isok 42 | 43 | CALL TEXT.APPEND message, ' (', message 44 | CALL TEXT.APPEND message, a, message 45 | CALL TEXT.APPEND message, '<>', message 46 | CALL TEXT.APPEND message, b, message 47 | CALL TEXT.APPEND message, ')', message 48 | 49 | CALL ASSERT.FAILED message 50 | isok: 51 | } 52 | 53 | subcall ASSERT.NOTEQUAL // SSSV ASSERT.FAILED 54 | { 55 | IN_S a 252 56 | IN_S b 252 57 | IN_S message 252 58 | 59 | DATA8 flag 60 | 61 | STRINGS COMPARE a b flag 62 | JR_EQ8 flag 0 isok 63 | CALL ASSERT.FAILED message 64 | isok: 65 | } 66 | 67 | subcall ASSERT.GREATER // FFSV ASSERT.FAILED 68 | { 69 | IN_F a 70 | IN_F b 71 | IN_S message 252 72 | 73 | JR_GTF a b isok 74 | CALL ASSERT.FAILED message 75 | isok: 76 | } 77 | 78 | subcall ASSERT.GREATEREQUAL // FFSV ASSERT.FAILED 79 | { 80 | IN_F a 81 | IN_F b 82 | IN_S message 252 83 | 84 | JR_GTEQF a b isok 85 | CALL ASSERT.FAILED message 86 | isok: 87 | } 88 | 89 | subcall ASSERT.LESS // FFSV ASSERT.FAILED 90 | { 91 | IN_F a 92 | IN_F b 93 | IN_S message 252 94 | 95 | JR_LTF a b isok 96 | CALL ASSERT.FAILED message 97 | isok: 98 | } 99 | 100 | subcall ASSERT.LESSEQUAL // FFSV ASSERT.FAILED 101 | { 102 | IN_F a 103 | IN_F b 104 | IN_S message 252 105 | 106 | JR_LTEQF a b isok 107 | CALL ASSERT.FAILED message 108 | isok: 109 | } 110 | 111 | subcall ASSERT.NEAR // FFSV ASSERT.FAILED 112 | { 113 | IN_F a 114 | IN_F b 115 | IN_S message 252 116 | 117 | DATAF tmp 118 | DATAF epsilon 119 | MOVE32_F 1 epsilon 120 | MOVE32_F 5000000 tmp 121 | DIVF epsilon tmp epsilon 122 | 123 | SUBF b epsilon tmp 124 | JR_LTF a tmp failed 125 | ADDF b epsilon tmp 126 | JR_GTF a tmp failed 127 | 128 | RETURN 129 | 130 | failed: 131 | CALL ASSERT.FAILED message 132 | } 133 | 134 | 135 | -------------------------------------------------------------------------------- /EV3BasicCompiler/Resources/Byte.txt: -------------------------------------------------------------------------------- 1 | // ------------------------------------------ EV3 MODULE: BYTE ------------------------------------------------- 2 | 3 | subcall BYTE.NOT // FF 4 | { 5 | IN_F value 6 | OUT_F result 7 | 8 | DATA16 value_16 9 | MOVEF_16 value value_16 10 | 11 | XOR16 value_16 255 value_16 12 | AND16 value_16 255 value_16 13 | MOVE16_F value_16 result 14 | } 15 | 16 | subcall BYTE.AND_ // FFF 17 | { 18 | IN_F value1 19 | IN_F value2 20 | OUT_F result 21 | 22 | DATA16 value1_16 23 | DATA16 value2_16 24 | MOVEF_16 value1 value1_16 25 | MOVEF_16 value2 value2_16 26 | 27 | AND16 value1_16 value2_16 value2_16 28 | AND16 value2_16 255 value2_16 29 | MOVE16_F value2_16 result 30 | } 31 | 32 | subcall BYTE.OR_ // FFF 33 | { 34 | IN_F value1 35 | IN_F value2 36 | OUT_F result 37 | 38 | DATA16 value1_16 39 | DATA16 value2_16 40 | MOVEF_16 value1 value1_16 41 | MOVEF_16 value2 value2_16 42 | 43 | OR16 value1_16 value2_16 value2_16 44 | AND16 value2_16 255 value2_16 45 | MOVE16_F value2_16 result 46 | } 47 | 48 | subcall BYTE.XOR // FFF 49 | { 50 | IN_F value1 51 | IN_F value2 52 | OUT_F result 53 | 54 | DATA16 value1_16 55 | DATA16 value2_16 56 | MOVEF_16 value1 value1_16 57 | MOVEF_16 value2 value2_16 58 | 59 | XOR16 value1_16 value2_16 value2_16 60 | AND16 value2_16 255 value2_16 61 | MOVE16_F value2_16 result 62 | } 63 | 64 | subcall BYTE.BIT // FFF 65 | { 66 | IN_F value 67 | IN_F index 68 | OUT_F result 69 | 70 | DATA16 value_16 71 | DATA16 index_16 72 | DATA8 result_8 73 | MOVEF_16 value value_16 74 | MOVEF_16 index index_16 75 | 76 | AND16 index_16 255 index_16 77 | RL16 1 index_16 index_16 78 | AND16 index_16 value_16 value_16 79 | CP_NEQ16 value_16 0 result_8 80 | MOVE8_F result_8 result 81 | } 82 | 83 | subcall BYTE.SHL // FFF 84 | { 85 | IN_F value 86 | IN_F distance 87 | OUT_F result 88 | 89 | DATA16 value_16 90 | DATA16 distance_16 91 | MOVEF_16 value value_16 92 | MOVEF_16 distance distance_16 93 | 94 | AND16 distance_16 255 distance_16 95 | RL16 value_16 distance_16 value_16 96 | AND16 value_16 255 value_16 97 | MOVE16_F value_16 result 98 | } 99 | 100 | subcall BYTE.SHR // FFF 101 | { 102 | IN_F value 103 | IN_F distance 104 | OUT_F result 105 | 106 | DATA16 value_16 107 | DATA16 distance_16 108 | MOVEF_16 value value_16 109 | MOVEF_16 distance distance_16 110 | 111 | AND16 distance_16 255 distance_16 112 | JR_GT16 distance_16 7 outside 113 | 114 | RL16 1 distance_16 distance_16 115 | DIV16 value_16 distance_16 value_16 116 | MOVE16_F value_16 result 117 | RETURN 118 | 119 | outside: 120 | MOVE16_F 0 result 121 | } 122 | 123 | subcall BYTE.TOHEX // FS 124 | { 125 | IN_F value 126 | OUT_S result 4 127 | 128 | DATA32 value_32 129 | MOVEF_32 value value_32 130 | 131 | AND32 value_32 255 value_32 132 | STRINGS NUMBER_FORMATTED value_32 '%02X' 3 result 133 | } 134 | 135 | subcall BYTE.TOBINARY // FS 136 | { 137 | IN_F value 138 | OUT_S result 10 139 | 140 | DATA32 value_32 141 | DATA32 x 142 | DATA32 y 143 | MOVEF_32 value value_32 144 | AND32 value_32 255 value_32 145 | 146 | // stretch bits so every bit is placed in an individual nibble 147 | RL32 value_32 12 y 148 | OR32 value_32 y x 149 | AND32 x 983055 x // mask bits 150 | RL32 x 6 y 151 | OR32 x y x 152 | RL32 x 3 y 153 | OR32 x y x 154 | AND32 x 286331153 x // mask bits 155 | 156 | STRINGS NUMBER_FORMATTED x '%08X' 9 result 157 | } 158 | 159 | subcall BYTE.TOLOGIC // FS 160 | { 161 | IN_F value 162 | OUT_S result 10 163 | 164 | JR_GTF value 0.0 delivertrue 165 | STRINGS DUPLICATE 'False' result 166 | RETURN 167 | delivertrue: 168 | STRINGS DUPLICATE 'True' result 169 | } 170 | 171 | subcall BYTE.H // SF 172 | { 173 | IN_S a 252 174 | OUT_F result 175 | 176 | DATA32 value 177 | DATA8 idx 178 | DATA8 char 179 | DATA32 digit 180 | 181 | MOVE32_32 0 value 182 | MOVE8_8 0 idx 183 | loop: 184 | READ8 a idx char 185 | JR_EQ8 char 0 done 186 | JR_LT8 char 48 next 187 | JR_GT8 char 57 checkuppercases 188 | MOVE8_32 char digit 189 | SUB32 digit 48 digit 190 | JR digitfound 191 | checkuppercases: 192 | JR_LT8 char 65 next 193 | JR_GT8 char 70 checklowercases 194 | MOVE8_32 char digit 195 | SUB32 digit 55 digit 196 | JR digitfound 197 | checklowercases: 198 | JR_LT8 char 97 next 199 | JR_GT8 char 102 next 200 | MOVE8_32 char digit 201 | SUB32 digit 87 digit 202 | digitfound: 203 | MUL32 value 16 value 204 | ADD32 value digit value 205 | next: 206 | JR_GT8 idx 126 done 207 | ADD8 idx 1 idx 208 | JR loop 209 | 210 | done: 211 | AND32 value 255 value 212 | MOVE32_F value result 213 | } 214 | 215 | subcall BYTE.B // SF 216 | { 217 | IN_S a 252 218 | OUT_F result 219 | 220 | DATA32 value 221 | DATA8 idx 222 | DATA8 char 223 | DATA32 digit 224 | 225 | MOVE32_32 0 value 226 | MOVE8_8 0 idx 227 | loop: 228 | READ8 a idx char 229 | JR_EQ8 char 0 done 230 | JR_LT8 char 48 next 231 | JR_GT8 char 49 next 232 | MOVE8_32 char digit 233 | SUB32 digit 48 digit 234 | MUL32 value 2 value 235 | ADD32 value digit value 236 | next: 237 | JR_GT8 idx 126 done 238 | ADD8 idx 1 idx 239 | JR loop 240 | 241 | done: 242 | AND32 value 255 value 243 | MOVE32_F value result 244 | } 245 | 246 | subcall BYTE.L // SF 247 | { 248 | IN_S a 252 249 | OUT_F result 250 | 251 | AND8888_32 a -538976289 a // AND 0xdfdfdfdf performs an upcase for 4 letters 252 | STRINGS COMPARE a 'TRUE' a 253 | JR_NEQ8 a 0 istrue 254 | MOVE8_F 0 result 255 | RETURN 256 | istrue: 257 | MOVE8_F 1 result 258 | } 259 | -------------------------------------------------------------------------------- /EV3BasicCompiler/Resources/EV3.txt: -------------------------------------------------------------------------------- 1 | // ------------------------------------------ EV3 MODULE: EV3 ------------------------------------------------- 2 | 3 | DATA16 FD_NATIVECODECOMMAND 4 | DATA16 FD_NATIVECODERESPONSE 5 | 6 | 7 | subcall EV3.SETLEDCOLOR // SSV 8 | { 9 | IN_S color 8 // only receive first 7 characters 10 | IN_S effect 8 // only receive first 7 characters 11 | 12 | ARRAY8 color_1 4 // split up to be able to do some operations with 4 bytes each 13 | ARRAY8 color_2 4 14 | ARRAY8 effect_1 4 15 | ARRAY8 effect_2 4 16 | 17 | STRINGS DUPLICATE color color_1 18 | STRINGS DUPLICATE effect effect_1 19 | AND8888_32 color_1 -538976289 color_1 // AND 0xdfdfdfdf performs an upcase for 4 letters 20 | AND8888_32 color_2 -538976289 color_2 // AND 0xdfdfdfdf performs an upcase for 4 letters 21 | AND8888_32 effect_1 -538976289 effect_1 // AND 0xdfdfdfdf performs an upcase for 4 letters 22 | AND8888_32 effect_2 -538976289 effect_2 // AND 0xdfdfdfdf performs an upcase for 4 letters 23 | 24 | DATA8 col 25 | DATA8 flag 26 | MOVE8_8 0 col 27 | 28 | STRINGS COMPARE color_1 'GREEN' flag 29 | JR_EQ8 flag 0 notgreen 30 | MOVE8_8 1 col 31 | JR checkeffect 32 | notgreen: 33 | STRINGS COMPARE color_1 'RED' flag 34 | JR_EQ8 flag 0 notred 35 | MOVE8_8 2 col 36 | JR checkeffect 37 | notred: 38 | STRINGS COMPARE color_1 'ORANGE' flag 39 | JR_EQ8 flag 0 setcol 40 | MOVE8_8 3 col 41 | checkeffect: 42 | 43 | STRINGS COMPARE effect_1 'FLASH' flag 44 | JR_EQ8 flag 0 noflash 45 | ADD8 col 3 col 46 | JR setcol 47 | noflash: 48 | STRINGS COMPARE effect_1 'PULSE' flag 49 | JR_EQ8 flag 0 setcol 50 | ADD8 col 6 col 51 | 52 | setcol: 53 | UI_WRITE LED col 54 | } 55 | 56 | subcall EV3.TIME // F 57 | { 58 | OUT_F time 59 | 60 | DATA32 ms 61 | DATAF thousand 62 | 63 | TIMER_READ ms 64 | MOVE32_F ms time 65 | } 66 | 67 | 68 | subcall EV3.BATTERYLEVEL // F 69 | { 70 | OUT_F level 71 | 72 | DATA8 l8 73 | UI_READ GET_LBATT l8 74 | MOVE8_F l8 level 75 | } 76 | 77 | subcall EV3.BATTERYVOLTAGE // F 78 | { 79 | OUT_F voltage 80 | UI_READ GET_VBATT voltage 81 | } 82 | 83 | subcall EV3.BATTERYCURRENT // F 84 | { 85 | OUT_F current 86 | UI_READ GET_IBATT current 87 | } 88 | 89 | subcall EV3.BRICKNAME // S 90 | { 91 | OUT_S result 252 92 | COM_GET GET_BRICKNAME 18 result 93 | } 94 | 95 | subcall EV3.SYSTEMCALL // SF 96 | { 97 | IN_S commandline 252 98 | OUT_F result 99 | 100 | DATA32 result32 101 | DATA8 result00 102 | DATA8 result01 103 | DATA8 result02 104 | DATA8 result03 105 | 106 | SYSTEM commandline result00 107 | MOVE8_32 result01 result32 108 | AND32 result32 255 result32 109 | 110 | MOVE32_F result32 result 111 | } 112 | 113 | inline EV3.QUEUENEXTCOMMAND // V 114 | { 115 | } 116 | 117 | subcall EV3.NATIVECODE // SF 118 | { 119 | IN_S command 252 120 | OUT_F response 121 | 122 | DATA8 errorcode00 123 | DATA8 errorcode01 124 | DATA8 errorcode02 125 | DATA8 errorcode03 126 | DATA32 filesize 127 | DATAS responsetxt 128 128 | 129 | // check if native code process is already running 130 | JR_NEQ16 0 FD_NATIVECODECOMMAND alreadyrunning 131 | 132 | // create/open named pipes 133 | SYSTEM 'mknod /tmp/nativecodecommand p' errorcode00 134 | SYSTEM 'mknod /tmp/nativecoderesponse p' errorcode00 135 | 136 | // fire up the native code process 137 | SYSTEM '/tmp/nativecode /tmp/nativecoderesponse &' errorcode00 138 | JR_NEQ8 errorcode01 0 errorclose 139 | 140 | FILE OPEN_WRITE '/tmp/nativecodecommand' FD_NATIVECODECOMMAND 141 | JR_LT16 FD_NATIVECODECOMMAND 1 errorclose 142 | FILE OPEN_READ '/tmp/nativecoderesponse' FD_NATIVECODERESPONSE filesize 143 | JR_LT16 FD_NATIVECODERESPONSE 1 errorclose 144 | 145 | alreadyrunning: 146 | FILE WRITE_TEXT FD_NATIVECODECOMMAND 6 command 147 | 148 | // DATA32 timer 149 | // TIMER_WAIT 5 timer 150 | // TIMER_READY timer 151 | 152 | FILE READ_TEXT FD_NATIVECODERESPONSE 6 127 responsetxt 153 | STRINGS STRING_TO_VALUE responsetxt response 154 | RETURN 155 | 156 | errorclose: 157 | JR_EQ16 FD_NATIVECODECOMMAND 0 notopen1 158 | FILE CLOSE FD_NATIVECODECOMMAND 159 | MOVE16_16 0 FD_NATIVECODECOMMAND 160 | notopen1: 161 | JR_EQ16 FD_NATIVECODERESPONSE 0 notopen2 162 | FILE CLOSE FD_NATIVECODERESPONSE 163 | MOVE16_16 0 FD_NATIVECODERESPONSE 164 | notopen2: 165 | MOVEF_F -1.0 response 166 | } 167 | 168 | 169 | -------------------------------------------------------------------------------- /EV3BasicCompiler/Resources/LCD.txt: -------------------------------------------------------------------------------- 1 | // ------------------------------------------ EV3 MODULE: LCD ------------------------------------------------- 2 | 3 | DATA32 STOPLCDUPDATE 4 | 5 | init 6 | { 7 | MOVE32_32 0 STOPLCDUPDATE 8 | } 9 | 10 | inline LCD.STOPUPDATE // V 11 | { 12 | MOVE32_32 1 STOPLCDUPDATE 13 | } 14 | 15 | inline LCD.UPDATE // V 16 | { 17 | MOVE32_32 0 STOPLCDUPDATE 18 | UI_DRAW UPDATE 19 | } 20 | 21 | subcall LCD.CLEAR // V 22 | { 23 | UI_DRAW(TOPLINE,0) 24 | UI_DRAW(CLEAN) 25 | 26 | JR_NEQ32 0 STOPLCDUPDATE skipupdate 27 | UI_DRAW UPDATE 28 | skipupdate: 29 | } 30 | 31 | subcall LCD.RECT // FFFFFV 32 | { 33 | IN_F col 34 | IN_F x 35 | IN_F y 36 | IN_F w 37 | IN_F h 38 | 39 | DATA8 col_8 40 | DATA16 x_16 41 | DATA16 y_16 42 | DATA16 w_16 43 | DATA16 h_16 44 | MOVEF_8 col col_8 45 | MOVEF_16 x x_16 46 | MOVEF_16 y y_16 47 | MOVEF_16 w w_16 48 | MOVEF_16 h h_16 49 | 50 | UI_DRAW RECT,col_8,x_16,y_16,w_16,h_16 51 | 52 | JR_NEQ32 0 STOPLCDUPDATE skipupdate 53 | UI_DRAW UPDATE 54 | skipupdate: 55 | } 56 | 57 | subcall LCD.LINE // FFFFFV 58 | { 59 | IN_F col 60 | IN_F x1 61 | IN_F y1 62 | IN_F x2 63 | IN_F y2 64 | 65 | DATA8 col_8 66 | DATA16 x1_16 67 | DATA16 y1_16 68 | DATA16 x2_16 69 | DATA16 y2_16 70 | MOVEF_8 col col_8 71 | MOVEF_16 x1 x1_16 72 | MOVEF_16 y1 y1_16 73 | MOVEF_16 x2 x2_16 74 | MOVEF_16 y2 y2_16 75 | 76 | UI_DRAW(LINE,col_8,x1_16,y1_16,x2_16,y2_16) 77 | 78 | JR_NEQ32 0 STOPLCDUPDATE skipupdate 79 | UI_DRAW UPDATE 80 | skipupdate: 81 | } 82 | 83 | subcall LCD.TEXT // FFFFSV 84 | { 85 | IN_F col 86 | IN_F x 87 | IN_F y 88 | IN_F font 89 | IN_S text 252 90 | 91 | DATA8 col_8 92 | DATA16 x_16 93 | DATA16 y_16 94 | DATA8 font_8 95 | MOVEF_8 col col_8 96 | MOVEF_16 x x_16 97 | MOVEF_16 y y_16 98 | MOVEF_8 font font_8 99 | 100 | UI_DRAW SELECT_FONT font_8 101 | UI_DRAW TEXT col_8 x_16 y_16 text 102 | 103 | JR_NEQ32 0 STOPLCDUPDATE skipupdate 104 | UI_DRAW UPDATE 105 | skipupdate: 106 | } 107 | 108 | subcall LCD.WRITE // FFSV 109 | { 110 | IN_F x 111 | IN_F y 112 | IN_S text 252 113 | 114 | DATA16 x_16 115 | DATA16 y_16 116 | MOVEF_16 x x_16 117 | MOVEF_16 y y_16 118 | 119 | UI_DRAW SELECT_FONT 1 120 | UI_DRAW TEXT 1 x_16 y_16 text 121 | 122 | JR_NEQ32 0 STOPLCDUPDATE skipupdate 123 | UI_DRAW UPDATE 124 | skipupdate: 125 | } 126 | 127 | subcall LCD.CIRCLE // FFFFV 128 | { 129 | IN_F col 130 | IN_F x 131 | IN_F y 132 | IN_F r 133 | 134 | DATA8 col_8 135 | DATA16 x_16 136 | DATA16 y_16 137 | DATA16 r_16 138 | MOVEF_8 col col_8 139 | MOVEF_16 x x_16 140 | MOVEF_16 y y_16 141 | MOVEF_16 r r_16 142 | 143 | UI_DRAW CIRCLE col_8 x_16 y_16 r_16 144 | 145 | JR_NEQ32 0 STOPLCDUPDATE skipupdate 146 | UI_DRAW UPDATE 147 | skipupdate: 148 | } 149 | 150 | subcall LCD.FILLCIRCLE // FFFFV 151 | { 152 | IN_F col 153 | IN_F x 154 | IN_F y 155 | IN_F r 156 | 157 | DATA8 col_8 158 | DATA16 x_16 159 | DATA16 y_16 160 | DATA16 r_16 161 | 162 | MOVEF_8 col col_8 163 | MOVEF_16 x x_16 164 | MOVEF_16 y y_16 165 | MOVEF_16 r r_16 166 | 167 | UI_DRAW FILLCIRCLE col_8 x_16 y_16 r_16 168 | 169 | JR_NEQ32 0 STOPLCDUPDATE skipupdate 170 | UI_DRAW UPDATE 171 | skipupdate: 172 | } 173 | 174 | subcall LCD.FILLRECT // FFFFFV 175 | { 176 | IN_F col 177 | IN_F x 178 | IN_F y 179 | IN_F w 180 | IN_F h 181 | 182 | DATA8 col_8 183 | DATA16 x_16 184 | DATA16 y_16 185 | DATA16 w_16 186 | DATA16 h_16 187 | MOVEF_8 col col_8 188 | MOVEF_16 x x_16 189 | MOVEF_16 y y_16 190 | MOVEF_16 w w_16 191 | MOVEF_16 h h_16 192 | 193 | UI_DRAW FILLRECT,col_8,x_16,y_16,w_16,h_16 194 | 195 | JR_NEQ32 0 STOPLCDUPDATE skipupdate 196 | UI_DRAW UPDATE 197 | skipupdate: 198 | } 199 | 200 | subcall LCD.INVERSERECT // FFFFV 201 | { 202 | IN_F x 203 | IN_F y 204 | IN_F w 205 | IN_F h 206 | 207 | DATA16 x_16 208 | DATA16 y_16 209 | DATA16 w_16 210 | DATA16 h_16 211 | 212 | MOVEF_16 x x_16 213 | MOVEF_16 y y_16 214 | MOVEF_16 w w_16 215 | MOVEF_16 h h_16 216 | 217 | UI_DRAW INVERSERECT,x_16,y_16,w_16,h_16 218 | 219 | JR_NEQ32 0 STOPLCDUPDATE skipupdate 220 | UI_DRAW UPDATE 221 | skipupdate: 222 | } 223 | 224 | subcall LCD.PIXEL // FFFV 225 | { 226 | IN_F col 227 | IN_F x 228 | IN_F y 229 | 230 | DATA8 col_8 231 | DATA16 x_16 232 | DATA16 y_16 233 | MOVEF_8 col col_8 234 | MOVEF_16 x x_16 235 | MOVEF_16 y y_16 236 | 237 | UI_DRAW PIXEL,col_8,x_16,y_16 238 | 239 | JR_NEQ32 0 STOPLCDUPDATE skipupdate 240 | UI_DRAW UPDATE 241 | skipupdate: 242 | } 243 | 244 | subcall LCD.BMPFILE // FFFSV 245 | { 246 | IN_F color 247 | IN_F x 248 | IN_F y 249 | IN_S filename 252 250 | 251 | DATA8 col_8 252 | DATA16 x_16 253 | DATA16 y_16 254 | DATAS fullname 300 255 | MOVEF_8 color col_8 256 | MOVEF_16 x x_16 257 | MOVEF_16 y y_16 258 | 259 | STRINGS DUPLICATE filename fullname 260 | JR_EQ8 filename 47 absolutepath // filename begins with a '/' 261 | STRINGS ADD '/home/root/lms2012/prjs/' filename fullname 262 | absolutepath: 263 | 264 | STRINGS ADD fullname '.rgf' fullname 265 | 266 | UI_DRAW BMPFILE col_8 x_16 y_16 fullname 267 | 268 | JR_NEQ32 0 STOPLCDUPDATE skipupdate 269 | UI_DRAW UPDATE 270 | skipupdate: 271 | } 272 | -------------------------------------------------------------------------------- /EV3BasicCompiler/Resources/Mailbox.txt: -------------------------------------------------------------------------------- 1 | // ------------------------------------------ EV3 MODULE: Mailbox ------------------------------------------------- 2 | 3 | DATA32 NUMMAILBOXES 4 | 5 | init 6 | { 7 | MOVE32_32 0 NUMMAILBOXES 8 | } 9 | 10 | 11 | subcall MAILBOX.CREATE // SF 12 | { 13 | IN_S boxname 252 14 | OUT_F id 15 | 16 | JR_GTEQ32 NUMMAILBOXES 30 toomanyboxes 17 | 18 | DATA8 id8 19 | MOVE32_F NUMMAILBOXES id 20 | MOVE32_8 NUMMAILBOXES id8 21 | ADD32 NUMMAILBOXES 1 NUMMAILBOXES 22 | MAILBOX_OPEN id8 boxname 4 0 0 23 | RETURN 24 | 25 | toomanyboxes: 26 | MOVEF_F -1.0 id 27 | RETURN 28 | } 29 | 30 | 31 | subcall MAILBOX.ISAVAILABLE // FS 32 | { 33 | IN_F id 34 | OUT_S result 252 35 | 36 | DATA8 id8 37 | DATA8 busy 38 | MOVEF_8 id id8 39 | 40 | MAILBOX_TEST id8 busy 41 | JR_EQ8 busy 0 available 42 | 43 | STRINGS DUPLICATE 'False' result 44 | RETURN 45 | 46 | available: 47 | STRINGS DUPLICATE 'True' result 48 | } 49 | 50 | inline MAILBOX.RECEIVE // FS 51 | { 52 | DATA8 no:# 53 | MOVEF_8 :0 no:# 54 | MAILBOX_READY no:# 55 | MAILBOX_READ no:# 252 1 :1 56 | } 57 | 58 | 59 | subcall MAILBOX.SEND // SSSV 60 | { 61 | IN_S brickname 252 62 | IN_S boxname 252 63 | IN_S message 252 64 | 65 | MAILBOX_WRITE brickname 0 boxname 4 1 message 66 | } 67 | 68 | 69 | subcall MAILBOX.CONNECT // SV 70 | { 71 | IN_S brickname 252 72 | 73 | COM_SET SET_CONNECTION 2 brickname 1 74 | } 75 | -------------------------------------------------------------------------------- /EV3BasicCompiler/Resources/Math.txt: -------------------------------------------------------------------------------- 1 | // ---------------------------------------- BASIC MODULE: MATH --------------------------------------- 2 | 3 | inline MATH.PI // F 4 | { 5 | MOVEF_F 3.1415926535897932384 :0 6 | } 7 | 8 | inline MATH.ABS // FF 9 | { 10 | MATH ABS :0 :1 11 | } 12 | inline MATH.ARCCOS // FF 13 | { 14 | DATAF tmpf:# 15 | MATH ACOS :0 tmpf:# 16 | DIVF tmpf:# 57.295779513082 :1 17 | } 18 | inline MATH.ARCSIN // FF 19 | { 20 | DATAF tmpf:# 21 | MATH ASIN :0 tmpf:# 22 | DIVF tmpf:# 57.295779513082 :1 23 | } 24 | inline MATH.ARCTAN // FF 25 | { 26 | DATAF tmpf:# 27 | MATH ATAN :0 tmpf:# 28 | DIVF tmpf:# 57.295779513082 :1 29 | } 30 | inline MATH.CEILING // FF 31 | { 32 | DATAF tmpf:# 33 | DATA8 flag:# 34 | MATH CEIL :0 tmpf:# 35 | CP_EQF tmpf:# 0.0 flag:# 36 | SELECTF flag:# 0.0 tmpf:# :1 37 | } 38 | inline MATH.COS // FF 39 | { 40 | DATAF tmpf:# 41 | MULF :0 57.295779513082 tmpf:# 42 | MATH COS tmpf:# :1 43 | } 44 | inline MATH.FLOOR // FF 45 | { 46 | MATH FLOOR 47 | } 48 | inline MATH.GETDEGREES // FF 49 | { 50 | MULF :0 57.295779513082 :1 51 | } 52 | inline MATH.GETRADIANS // FF 53 | { 54 | DIVF :0 57.295779513082 :1 55 | } 56 | subcall MATH.GETRANDOMNUMBER // FF 57 | { 58 | IN_F range 59 | OUT_F result 60 | 61 | DATA16 range_16 62 | DATA16 value 63 | MOVEF_16 range range_16 64 | 65 | RANDOM 1 range_16 value 66 | MOVE16_F value result 67 | } 68 | inline MATH.LOG // FF 69 | { 70 | MATH LOG 71 | } 72 | inline MATH.MAX // FFF 73 | { 74 | DATA8 flag:# 75 | CP_GTF :0 :1 flag:# 76 | SELECTF flag:# :0 :1 :2 77 | } 78 | inline MATH.MIN // FFF 79 | { 80 | DATA8 flag:# 81 | CP_LTF :0 :1 flag:# 82 | SELECTF flag:# :0 :1 :2 83 | } 84 | inline MATH.NATURALLOG // FF 85 | { 86 | MATH LN 87 | } 88 | inline MATH.POWER // FFF 89 | { 90 | MATH POW 91 | } 92 | inline MATH.REMAINDER // FFF 93 | { 94 | MATH MOD 95 | } 96 | inline MATH.ROUND // FF 97 | { 98 | MATH ROUND 99 | } 100 | inline MATH.SIN // FF 101 | { 102 | DATAF tmpf:# 103 | MULF :0 57.295779513082 tmpf:# 104 | MATH SIN tmpf:# :1 105 | } 106 | inline MATH.SQUAREROOT // FF 107 | { 108 | MATH SQRT 109 | } 110 | inline MATH.TAN // FF 111 | { 112 | DATAF tmpf:# 113 | MULF :0 57.295779513082 tmpf:# 114 | MATH TAN tmpf:# :1 115 | } 116 | 117 | -------------------------------------------------------------------------------- /EV3BasicCompiler/Resources/Program.txt: -------------------------------------------------------------------------------- 1 | // ------------------------------------------ BASIC MODULE: PROGRAM ------------------------------------------------- 2 | 3 | subcall PROGRAM.ARGUMENTCOUNT // F 4 | { 5 | OUT_F result 6 | MOVE8_F 0 result 7 | } 8 | 9 | subcall PROGRAM.DIRECTORY // S 10 | { 11 | OUT_S result 128 12 | FILENAME(GET_FOLDERNAME,127,result) 13 | } 14 | 15 | subcall PROGRAM.GETARGUMENT // FS 16 | { 17 | IN_F index 18 | OUT_S result 8 19 | STRINGS DUPLICATE '' result 20 | } 21 | 22 | 23 | inline PROGRAM.DELAY // FV 24 | { 25 | DATA32 milliseconds:# 26 | MOVEF_32 :0 milliseconds:# 27 | DATA32 timer:# 28 | TIMER_WAIT milliseconds:# timer:# 29 | TIMER_READY timer:# 30 | } 31 | 32 | inline PROGRAM.END // V 33 | { 34 | PROGRAM_STOP -1 35 | } 36 | 37 | -------------------------------------------------------------------------------- /EV3BasicCompiler/Resources/Speaker.txt: -------------------------------------------------------------------------------- 1 | // ------------------------------------------ EV3 MODULE: SPEAKER ------------------------------------------------- 2 | 3 | inline SPEAKER.STOP // V 4 | { 5 | SOUND BREAK 6 | } 7 | 8 | subcall SPEAKER.TONE // FFFV 9 | { 10 | IN_F volume 11 | IN_F tone 12 | IN_F duration 13 | 14 | DATA8 vol 15 | DATA16 tne 16 | DATA16 dur 17 | MOVEF_8 volume vol 18 | MOVEF_16 tone tne 19 | MOVEF_16 duration dur 20 | 21 | SOUND TONE vol tne dur 22 | } 23 | 24 | subcall SPEAKER.NOTE // FSFV 25 | { 26 | IN_F volume 27 | IN_S note 8 28 | IN_F duration 29 | 30 | DATA8 vol 31 | DATA16 tne 32 | DATA16 dur 33 | MOVEF_8 volume vol 34 | NOTE_TO_FREQ note tne 35 | MOVEF_16 duration dur 36 | 37 | SOUND TONE vol tne dur 38 | } 39 | 40 | subcall SPEAKER.PLAY // FSV 41 | { 42 | IN_F volume 43 | IN_S filename 252 44 | 45 | // prepend a path to really reach the target file from the current working directory 46 | DATA8 vol 47 | DATAS fullname 300 48 | MOVEF_8 volume vol 49 | 50 | STRINGS ADD '../../../..' filename fullname // when using absolute path, go to file system top from the VM directory and then back down 51 | JR_EQ8 filename 47 absolutepath // filename begins with a '/' - using absolute path 52 | STRINGS ADD '../prjs/' filename fullname // by default use path relative to prjs folder (must go from the current VM directory to there) 53 | absolutepath: 54 | 55 | SOUND PLAY vol fullname 56 | } 57 | 58 | subcall SPEAKER.ISBUSY // S 59 | { 60 | OUT_S result 8 61 | 62 | DATA8 busy 63 | SOUND_TEST busy 64 | JR_EQ8 busy 0 notbusy 65 | STRINGS DUPLICATE 'True' result 66 | RETURN 67 | notbusy: 68 | STRINGS DUPLICATE 'False' result 69 | RETURN 70 | } 71 | 72 | inline SPEAKER.WAIT // V 73 | { 74 | SOUND_READY 75 | } 76 | 77 | -------------------------------------------------------------------------------- /EV3BasicCompiler/Resources/Thread.txt: -------------------------------------------------------------------------------- 1 | // -------------------------------------- EXTENSION MODULE: THREAD -------------------------------------------- 2 | 3 | ARRAY16 LOCKS 2 // Handle to byte-array for locking 4 | // This array must only be created/extended by the subcall THREAD.CREATEMUTEX 5 | // Modification of individual elements must only be done by the subcall GETANDSETLOCK 6 | init 7 | { 8 | ARRAY CREATE8 0 LOCKS 9 | } 10 | 11 | // This method uses the property of the VM, that a subcall can not be 12 | // re-called by a thread while it is still running in another thread. 13 | // It does a get and increment action, incrementing a counter 14 | // and returning the original value in a seperate (thread-local) variable, 15 | // which can not be interrupted by another GETANDINC32 of other threads 16 | subcall GETANDINC32 // V 17 | { 18 | IN_32 counterin 19 | IN_32 inc 20 | OUT_32 counterout 21 | OUT_32 prev 22 | 23 | MOVE32_32 counterin prev 24 | ADD32 counterin inc counterout 25 | } 26 | 27 | // This method can be used to do an atomic test-and-set action on a 28 | // a value in a byte array. It can not be interrupted by a TESTANDSET 29 | // which is called in another thread, but it can be interrupted by 30 | // any other action of other threads. 31 | subcall GETANDSETLOCK // V 32 | { 33 | IN_F index // index as float as being used in Basic. 34 | // when not valid do nothing and return newvalue as oldvalue (prevent aquiring lock) 35 | IN_8 newvalue // set to this value 36 | OUT_8 oldvalue // return previous value 37 | 38 | DATA32 size 39 | DATA32 idx 40 | MOVEF_32 index idx 41 | ARRAY SIZE LOCKS size 42 | JR_LT32 idx 0 outofbounds 43 | JR_GTEQ32 idx size outofbounds 44 | 45 | ARRAY_READ LOCKS idx oldvalue 46 | ARRAY_WRITE LOCKS idx newvalue 47 | RETURN 48 | 49 | outofbounds: 50 | MOVE8_8 newvalue oldvalue 51 | } 52 | 53 | 54 | inline THREAD.YIELD // V 55 | { 56 | SLEEP 57 | } 58 | 59 | subcall THREAD.CREATEMUTEX // F 60 | { 61 | OUT_F index 62 | 63 | DATA8 zero 64 | MOVE8_8 0 zero 65 | 66 | DATA32 idx 67 | ARRAY SIZE LOCKS idx 68 | ARRAY_APPEND LOCKS zero 69 | 70 | MOVE32_F idx index 71 | } 72 | 73 | inline THREAD.LOCK // FV GETANDSETLOCK 74 | { 75 | DATA8 previous:# 76 | tryaquire:#: 77 | CALL GETANDSETLOCK :0 1 previous:# 78 | JR_EQ8 0 previous:# success:# 79 | SLEEP 80 | JR tryaquire:# 81 | success:#: 82 | } 83 | 84 | inline THREAD.UNLOCK // FV GETANDSETLOCK 85 | { 86 | DATA8 dummy:# 87 | CALL GETANDSETLOCK :0 0 dummy:# 88 | } 89 | 90 | -------------------------------------------------------------------------------- /EV3Communication/BinaryBuffer.cs: -------------------------------------------------------------------------------- 1 | /* EV3-Basic: A basic compiler to target the Lego EV3 brick 2 | Copyright (C) 2015 Reinhard Grafl 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Text; 21 | 22 | namespace EV3Communication 23 | { 24 | public class BinaryBuffer 25 | { 26 | private byte[] buffer; 27 | private int len; 28 | 29 | public BinaryBuffer() 30 | { 31 | buffer = new byte[20]; 32 | len = 0; 33 | } 34 | 35 | public int Length 36 | { 37 | get { return len; } 38 | } 39 | 40 | public void Clear() 41 | { 42 | len = 0; 43 | } 44 | 45 | public void CopyTo(byte[] target, int position) 46 | { 47 | System.Array.Copy(buffer, 0, target, position, len); 48 | } 49 | 50 | public void CopyTo(BinaryBuffer target) 51 | { 52 | target.AppendBytes(buffer, 0, len); 53 | } 54 | 55 | 56 | public void Append8(int i) 57 | { 58 | if (len >= buffer.Length) 59 | { 60 | byte[] buffer2 = new byte[buffer.Length * 2]; 61 | buffer.CopyTo(buffer2, 0); 62 | buffer = buffer2; 63 | } 64 | buffer[len] = (byte)i; 65 | len++; 66 | } 67 | 68 | public void Append16(int i) 69 | { 70 | Append8(i & 0xff); 71 | Append8((i>>8) & 0xff); 72 | } 73 | 74 | public void Append32(int i) 75 | { 76 | Append8(i & 0xff); 77 | Append8((i >> 8) & 0xff); 78 | Append8((i >> 16) & 0xff); 79 | Append8((i >> 24) & 0xff); 80 | } 81 | 82 | public void AppendBytes(byte[] b) 83 | { 84 | AppendBytes(b, 0, b.Length); 85 | } 86 | 87 | public void AppendBytes(byte[] b, int start, int length) 88 | { 89 | for (int i = 0; i < length; i++) 90 | { 91 | Append8(b[start+i]); 92 | } 93 | } 94 | 95 | public void AppendZeroTerminated(String s) 96 | { 97 | AppendNonZeroTerminated(s); 98 | Append8(0); 99 | } 100 | 101 | public void AppendNonZeroTerminated(String s) 102 | { 103 | for (int i = 0; i < s.Length; i++) 104 | { 105 | int c = s[i]; 106 | if (c<=0 || c>255) 107 | { 108 | Append8(1); 109 | } 110 | else 111 | { 112 | Append8(c); 113 | } 114 | } 115 | } 116 | 117 | 118 | public static int Extract16(byte[] buffer, int position) 119 | { 120 | int b1 = ((int)buffer[position]) & 0xff; 121 | int b2 = ((int)buffer[position+1]) & 0xff; 122 | return b1 + (b2 << 8); 123 | } 124 | public static int Extract32(byte[] buffer, int position) 125 | { 126 | int b1 = ((int)buffer[position]) & 0xff; 127 | int b2 = ((int)buffer[position + 1]) & 0xff; 128 | int b3 = ((int)buffer[position + 2]) & 0xff; 129 | int b4 = ((int)buffer[position + 3]) & 0xff; 130 | return b1 + (b2 << 8) + (b2 << 16) + (b3 << 24); 131 | } 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /EV3Communication/ByteCodeBuffer.cs: -------------------------------------------------------------------------------- 1 | /* EV3-Basic: A basic compiler to target the Lego EV3 brick 2 | Copyright (C) 2015 Reinhard Grafl 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Text; 21 | 22 | namespace EV3Communication 23 | { 24 | public class ByteCodeBuffer : BinaryBuffer 25 | { 26 | public ByteCodeBuffer() : base() 27 | { } 28 | 29 | public void OP(byte opcode) 30 | { 31 | Append8(opcode); 32 | } 33 | 34 | public void CONST(int par) 35 | { 36 | if (par >= -32 && par <= 31) 37 | { 38 | Append8(par & 0x3f); 39 | } 40 | else if (par >= -128 && par <= 127) 41 | { 42 | Append8(0x81); 43 | Append8(par); 44 | } 45 | else if (par >= -32768 && par <= 32767) 46 | { 47 | Append8(0x82); 48 | Append16(par); 49 | } 50 | else 51 | { 52 | Append8(0x83); 53 | Append32(par); 54 | } 55 | } 56 | 57 | public void GLOBVAR(int var) 58 | { 59 | if (var <= 31) 60 | { 61 | Append8((var & 0x1f) | 0x60); 62 | } 63 | else if (var <= 255) 64 | { 65 | Append8(0xe1); 66 | Append8(var); 67 | } 68 | else if (var <= 65535) 69 | { 70 | Append8(0xe2); 71 | Append16(var); 72 | } 73 | else 74 | { 75 | Append8(0xe3); 76 | Append32(var); 77 | } 78 | } 79 | 80 | public void LOCVAR(int var) 81 | { 82 | if (var <= 31) 83 | { 84 | Append8((var & 0x1f) | 0x40); 85 | } 86 | else if (var <= 255) 87 | { 88 | Append8(0xc1); 89 | Append8(var); 90 | } 91 | else if (var <= 65535) 92 | { 93 | Append8(0xc2); 94 | Append16(var); 95 | } 96 | else 97 | { 98 | Append8(0xc3); 99 | Append32(var); 100 | } 101 | } 102 | 103 | public void STRING(String text) 104 | { 105 | Append8(0x84); 106 | AppendZeroTerminated(text); 107 | } 108 | 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /EV3Communication/ConnectionTypeDialog.xaml: -------------------------------------------------------------------------------- 1 |  7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /EV3Explorer/QuestionBox.xaml.cs: -------------------------------------------------------------------------------- 1 | /* EV3-Basic: A basic compiler to target the Lego EV3 brick 2 | Copyright (C) 2015 Reinhard Grafl 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Text; 21 | using System.Windows; 22 | using System.Windows.Controls; 23 | using System.Windows.Data; 24 | using System.Windows.Documents; 25 | using System.Windows.Input; 26 | using System.Windows.Media; 27 | using System.Windows.Media.Imaging; 28 | using System.Windows.Shapes; 29 | 30 | namespace EV3Explorer 31 | { 32 | /// 33 | /// Interaction logic for QuestionBox.xaml 34 | /// 35 | public partial class QuestionBox : Window 36 | { 37 | 38 | public QuestionBox(string question, string defaultAnswer = "") 39 | { 40 | InitializeComponent(); 41 | lblQuestion.Content = question; 42 | txtAnswer.Text = defaultAnswer; 43 | } 44 | 45 | private void btnDialogOk_Click(object sender, RoutedEventArgs e) 46 | { 47 | this.DialogResult = true; 48 | } 49 | 50 | private void Window_ContentRendered(object sender, EventArgs e) 51 | { 52 | txtAnswer.SelectAll(); 53 | txtAnswer.Focus(); 54 | } 55 | 56 | public string Answer 57 | { 58 | get { return txtAnswer.Text; } 59 | } 60 | 61 | 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /EV3Explorer/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Examples/ActionLoop.sb: -------------------------------------------------------------------------------- 1 | ' Example - Vehicle that stops before an obstacle 2 | 3 | ' Go 4 | Motor.Start("A",50) 5 | 6 | While "True" 7 | 8 | ' IR-Sensor (on port 1) reads distance to obstacle and stops model 9 | If Sensor.ReadPercent(1) < 15 then 10 | Motor.Stop("A","True") 11 | endif 12 | ' press on touch sensor (port 2) restarts model 13 | If Sensor.ReadPercent(2)=100 Then 14 | Motor.Start("A",50) 15 | endif 16 | 17 | ' independently change led colors every 3 seconds 18 | F = Math.Remainder(Math.Floor(EV3.Time/3000), 3) 19 | If f=0 Then 20 | EV3.SetLEDColor("RED", "NORMAL") 21 | ElseIf F=1 then 22 | EV3.SetLEDColor("ORANGE", "NORMAL") 23 | ElseIf F=2 then 24 | EV3.SetLEDColor("GREEN", "NORMAL") 25 | endif 26 | 27 | ' make the loop not go too fast 28 | Program.Delay(10) 29 | 30 | EndWhile 31 | -------------------------------------------------------------------------------- /Examples/Battery.sb: -------------------------------------------------------------------------------- 1 | ' try to stop motor by hand to see increased current draw and voltage drop 2 | Motor.Start("A",10) 3 | 4 | While "true" 5 | LCD.StopUpdate() 6 | LCD.Clear() 7 | LCD.Text(1, 10,5, 1, "Battery Level") 8 | LCD.Text(1, 10,20, 1, EV3.BatteryLevel) 9 | LCD.Text(1, 10,40, 1, "Battery Voltage") 10 | LCD.Text(1, 10,55, 1, EV3.BatteryVoltage) 11 | LCD.Text(1, 10,75, 1, "Battery Current") 12 | LCD.Text(1, 10,90, 1, EV3.BatteryCurrent) 13 | LCD.Update() 14 | Program.Delay(100) 15 | endwhile 16 | -------------------------------------------------------------------------------- /Examples/BlockingOperations.sb: -------------------------------------------------------------------------------- 1 | ' Demonstration that a built-in function can not be running multiple times in parallel. 2 | ' For longer-lasting function calls (like a sort), this means all other threads have to 3 | ' wait until the call is finished before their operation starts. 4 | ' 5 | ' This is not true for built-in functions whose designed purpose is to wait for some 6 | ' event or time-span (like Program.Delay). Those functions can be used by multiple 7 | ' threads concurrently. 8 | 9 | LCD.Clear() 10 | 11 | SMALL = Vector.Init(5, 141) 12 | BIG = Vector.Init(500, 17) 13 | 14 | Thread.Run = SUB2 15 | Program.Delay(20) 16 | Thread.Run = SUB1 17 | 18 | Program.Delay(100000) 19 | 20 | Sub SUB1 21 | LCD.Text(1, 0,12, 1, "Small sort starting") 22 | A = Vector.Sort(5, SMALL) 23 | LCD.Text(1, 0,24, 1, "Small sort finished") 24 | EndSub 25 | 26 | Sub SUB2 27 | LCD.Text(1, 0, 48, 1, "Big sort starting") 28 | A = Vector.Sort(500, BIG) 29 | LCD.Text(1, 0,60, 1, "Big sort finished") 30 | EndSub 31 | 32 | -------------------------------------------------------------------------------- /Examples/ButtonsAndMotors.sb: -------------------------------------------------------------------------------- 1 | LCD.Clear() 2 | LCD.Text(1, 0,30, 1, "Control motors with") 3 | LCD.Text(1, 0,45, 1, "directional buttons") 4 | LCD.Text(1, 0,70, 1, "Left/Right: Motor A") 5 | LCD.Text(1, 0,85, 1, "Up/Down: Motor B") 6 | 7 | while "True" 8 | ' request button state 9 | K = Buttons.Current 10 | 11 | SA = 0 12 | SB = 0 13 | If Text.IsSubText(K, "L") then 14 | SA = -50 15 | elseif Text.IsSubText(K, "R") then 16 | SA = 50 17 | endif 18 | If Text.IsSubText(K, "U") then 19 | SB = -50 20 | elseif Text.IsSubText(K, "D") then 21 | SB = 50 22 | endif 23 | 24 | ' Adjust motor power 25 | Motor.StartPower("A", SA) 26 | Motor.StartPower("B", SB) 27 | 28 | ' wait a little before polling again 29 | Program.Delay(100) 30 | Endwhile 31 | -------------------------------------------------------------------------------- /Examples/Byte.sb: -------------------------------------------------------------------------------- 1 | ' do some byte operations and check for correct results 2 | 3 | ' simple bit operations 4 | Assert.Equal( Byte.NOT(33,), 222, "NOT 1") 5 | Assert.Equal( Byte.NOT(255,), 0, "NOT 2") 6 | Assert.Equal( Byte.AND_(33,15), 1, "AND 1") 7 | Assert.Equal( Byte.AND_(17,1), 1, "AND 2") 8 | Assert.Equal( Byte.OR_(16,3), 19, "OR 1") 9 | Assert.Equal( Byte.OR_(128,1), 129, "OR 2") 10 | Assert.Equal( Byte.XOR(16,255), 239, "XOR 1") 11 | Assert.Equal( Byte.XOR(16,16), 0, "XOR 2") 12 | Assert.Equal( Byte.BIT(31,1), 1, "BIT 1") 13 | Assert.Equal( Byte.BIT(31,5), 0, "BIT 2") 14 | Assert.Equal( Byte.BIT(255,30), 0, "BIT 3") 15 | Assert.Equal( Byte.BIT(255,-6), 0, "BIT 4") 16 | Assert.Equal( Byte.SHL(31,2), 31*4, "SHL 1") 17 | Assert.Equal( Byte.SHL(127,7), 128, "SHL 2") 18 | Assert.Equal( Byte.SHL(255,11), 0, "SHL 3") 19 | Assert.Equal( Byte.SHL(100,0), 100, "SHL 4") 20 | Assert.Equal( Byte.SHR(31,2), 7, "SHR 1") 21 | Assert.Equal( Byte.SHR(127,5), 3, "SHR 2") 22 | Assert.Equal( Byte.SHR(128,10), 0, "SHR 3") 23 | Assert.Equal( Byte.SHR(129,0), 129, "SHR 4") 24 | 25 | ' conversion 26 | Assert.Equal( Byte.B("00110010"), 50, "B 1") 27 | Assert.Equal( Byte.B("011"), 3, "B 2") 28 | Assert.Equal( Byte.H("fF"), 255, "H 1") 29 | Assert.Equal( Byte.H("D3"), 211, "H 2") 30 | Assert.Equal( Byte.L("TRUE"), 1, "L 2") 31 | Assert.Equal( Byte.L("TrUe"), 1, "L 2") 32 | Assert.Equal( Byte.L("False"), 0, "L 3") 33 | Assert.Equal( Byte.ToHex(255), "FF", "TOHEX 1") 34 | Assert.Equal( Byte.ToHex(211), "D3", "TOHEX 2") 35 | Assert.Equal( Byte.ToBinary(50), "00110010", "TOBINARY 1") 36 | Assert.Equal( Byte.ToBinary(3), "00000011", "TOBINARY 2") 37 | Assert.Equal( Byte.ToLogic(1), "True", "TOLOGIC 1") 38 | Assert.Equal( Byte.ToLogic(0), "False", "TOLOGIC 2") 39 | Assert.Equal( Byte.ToLogic(0.1), "True", "TOLOGIC 3") 40 | Assert.Equal( Byte.ToLogic(-0.1), "False", "TOLOGIC 4") 41 | 42 | Program.Delay(10000) 43 | -------------------------------------------------------------------------------- /Examples/ClickTest.sb: -------------------------------------------------------------------------------- 1 | LCD.Clear() 2 | LCD.Text(1, 0,30, 1, "Control motors with") 3 | LCD.Text(1, 0,45, 1, "button clicks") 4 | LCD.Text(1, 0,70, 1, "Left/Right: Motor A") 5 | LCD.Text(1, 0,85, 1, "Up/Down: Motor B") 6 | 7 | While "True" 8 | 9 | EV3.SetLEDColor("RED", "NORMAL") 10 | Buttons.Wait() 11 | EV3.SetLEDColor("OFF", "NORMAL") 12 | 13 | K = Buttons.GetClicks() 14 | If Text.IsSubText(K,"U") Then 15 | Motor.MovePower("A", 100, 500, "True") 16 | elseIf Text.IsSubText(K,"D") then 17 | Motor.MovePower("A", -100, 500 "True") 18 | EndIf 19 | If Text.IsSubText(K,"L") Then 20 | Motor.MovePower("B", 100, 500 "True") 21 | elseIf Text.IsSubText(K,"R") then 22 | Motor.MovePower("B", -100, 500 "True") 23 | EndIf 24 | 25 | If Text.ISSubText(Buttons.Current, "E") Then 26 | Buttons.Flush() 27 | endif 28 | 29 | EndWhile 30 | 31 | -------------------------------------------------------------------------------- /Examples/Concurrency.sb: -------------------------------------------------------------------------------- 1 | ' Complex example that combines recursive functions with multiple threads. 2 | ' This program will solve 4 instances of the towers of hanoi problem in parallel. 3 | 4 | ' Global storage for the disk stacks (3 x 4 stacks in total) 5 | STACK[0] = "HGFEDCBA" 6 | STACK[1] = "" 7 | STACK[2] = "" 8 | STACK[3] = "HGFEDCBA" 9 | STACK[4] = "" 10 | STACK[5] = "" 11 | STACK[6] = "HGFEDCBA" 12 | STACK[7] = "" 13 | STACK[8] = "" 14 | STACK[9] = "HGFEDCBA" 15 | STACK[10] = "" 16 | STACK[11] = "" 17 | ' Access to the global objects needs to be guarded with a Mutex 18 | MUTEX = Thread.CreateMutex() 19 | 20 | ' Atomic modification of global data (accesses global variables for intermediate storage while holding lock) 21 | F.Start = MOVE 22 | F.Function("MOVe", "FRom to:0") 23 | Sub MOVE 24 | Thread.Lock(MUTEX) 25 | 26 | ' transfer last letter 27 | F = STACK[F.Get("FROM")] 28 | T = STACK[F.Get("To")] 29 | STACK[F.Get("FrOM")] = Text.GetSubText(F, 1, Text.GetLength(F)-1) 30 | STACK[F.Get("TO")] = Text.Append(T, Text.GetSubText(F,Text.GetLength(F),1)) 31 | 32 | ' paint situation to screen 33 | LCD.StopUpdate() 34 | LCD.Clear() 35 | For S=0 To 11 36 | H = Text.GetLength(STACK[S]) 37 | For D=0 To H-1 38 | X = 15 + Math.Remainder(S,6) * 29 39 | Y = 58 + Math.Floor(S/6) * 64 - D*7 40 | W = 3.5 * (Text.GetCharacterCode(Text.GetSubText(STACK[S],D+1,1)) - 64) 41 | LCD.FillRect(1, X-W/2, Y, W, 6) 42 | EndFor 43 | EndFor 44 | LCD.Update() 45 | 46 | Thread.Unlock(MUTEX) 47 | EndSub 48 | 49 | ' Recursive algorithm 50 | F.Start = HANOI 51 | F.Function("HANOI", "SPEED FROM MIDDLE TO DISKS:1") 52 | Sub HANOI 53 | If F.Get("DISKS")<2 Then 54 | F.Call2("MOVE", F.Get("FROM"), F.Get("TO")) 55 | Program.Delay(F.Get("SPEED")) 56 | Else 57 | F.Call5("HANOI", F.Get("SPEED"), F.Get("FROM"), F.Get("TO"), F.Get("MIDDLE"), F.Get("DISKS")-1) 58 | F.Call4("HANOI", F.Get("SPEED"), F.Get("FROM"), -1, F.Get("TO")) 59 | F.Call5("HANOI", F.Get("SPEED"), F.Get("MIDDLE"), F.Get("FROM"), F.Get("TO"), F.Get("DISKS")-1) 60 | EndIf 61 | EndSub 62 | 63 | ' Start the solve runs as individual threads with different speeds 64 | Thread.Run = THREAD1 65 | Thread.Run = THREAD2 66 | Thread.Run = THREAD3 67 | Thread.Run = THREAD4 68 | Program.Delay(1000000) ' prevent program from automatic termination 69 | 70 | Sub THREAD1 71 | F.Call5("HANOI", 1000, 0,1,2, 8) 72 | EndSub 73 | Sub THREAD2 74 | F.Call5("HANOI", 1250, 3,4,5, 8) 75 | EndSub 76 | Sub THREAD3 77 | F.Call5("HANOI", 1500, 6,7,8, 8) 78 | EndSub 79 | Sub THREAD4 80 | F.Call5("HANOI", 1750, 9,10,11, 8) 81 | EndSub 82 | 83 | -------------------------------------------------------------------------------- /Examples/DaisyChain.sb: -------------------------------------------------------------------------------- 1 | 2 | While "True" 3 | LCD.StopUpdate() 4 | LCD.Clear() 5 | LCD.Text(1,0,2,1, "Plug touch sensors to") 6 | LCD.Text(1,0,14,1, "the daisy chain bricks") 7 | LCD.Text(1,0,26,1, "to control the motors") 8 | 9 | For l=1 To 4 10 | For s=1 To 4 11 | m = l + Text.GetCharacter(64+s) 12 | P = Sensor.ReadPercent(s+(l-1)*4) 13 | x = s*40 - 30 14 | y = l*20 + 25 15 | If P>50 Then 16 | LCD.FillRect(1,x,y, 30,18) 17 | LCD.Text(1,x+2,y+5, 1, P) 18 | Motor.Start(m,50) 19 | else 20 | LCD.Rect(1,x,y,30,18) 21 | LCD.Text(1,x+10,y+5, 1, P) 22 | Motor.Stop(m,"true") 23 | Endif 24 | endfor 25 | endfor 26 | LCD.Update() 27 | 28 | Program.Delay(100) 29 | EndWhile 30 | -------------------------------------------------------------------------------- /Examples/File.sb: -------------------------------------------------------------------------------- 1 | ' Example for file access 2 | 3 | ' write stuff to a file 4 | f = EV3File.OpenWrite("data.txt") 5 | EV3File.WriteByte(f,47) 6 | EV3File.WriteByte(f,8) 7 | EV3File.WriteLine(f,"so many words") 8 | A[0] = 4.6 9 | A[1] = 7 10 | A[2] = 66.3 11 | EV3File.WriteNumberArray(f,3,A) 12 | EV3File.WriteLine(f,"the end") 13 | EV3File.Close(f) 14 | 15 | ' read back everything and write to screen 16 | f = EV3File.OpenRead("data.txt") 17 | LCD.Clear() 18 | LCD.Write(10,10, EV3File.ReadByte(f)) 19 | LCD.Write(50,10, EV3File.ReadByte(f)) 20 | LCD.Write(10,30, EV3File.ReadLine(f)) 21 | B = EV3File.ReadNumberArray(f, 3) 22 | LCD.Write(10,50, B[0]) 23 | LCD.Write(10,65, B[1]) 24 | LCD.Write(10,80, B[2]) 25 | LCD.Write(10,100, EV3File.ReadLine(f)) 26 | EV3File.Close(f) 27 | 28 | Program.Delay(100000) 29 | -------------------------------------------------------------------------------- /Examples/Function.sb: -------------------------------------------------------------------------------- 1 | ' Simple function call demonstration without recursion but with 2 | ' numerical call parameters and return value. 3 | F.Start = SUM6 4 | F.Function("SUM6", "A B C D E F") 5 | Sub SUM6 6 | F.ReturnNumber(F.Call2("SUM", F.Call3("SUM3", F.Get("A"), F.Get("B"), F.Get("C")), F.Call3("SUM3", F.Get("D"), F.Get("E"), F.Get("F")))) 7 | EndSub 8 | 9 | F.Start = SUM3 10 | F.Function("SUM3", "A B C") 11 | Sub SUM3 12 | F.ReturnNumber(F.Call2("SUM", F.Get("A"), F.Call2("SUM", F.Get("B"), F.Get("C")))) 13 | EndSub 14 | 15 | F.Start = SUM 16 | F.Function("SUM", "A B") 17 | Sub SUM 18 | F.ReturnNumber(F.Get("A")+F.Get("B")) 19 | EndSub 20 | 21 | 22 | ' Demonstrate more exotic functions features: Default parameters, 23 | ' function consisting of multiple subprograms, local variables 24 | F.Start = LOWEST 25 | F.Function("LOWEST", "A:1 B:2 C:3 ISLOWER:False") 26 | Sub LOWEST 27 | If F.Get("A") < F.Get("B") Then 28 | TEST_A_LOWER_C() 29 | If F.Get("ISLOWER") Then 30 | F.ReturnText("FIRST") 31 | Endif 32 | Else 33 | TEST_B_LOWER_C() 34 | If F.Get("ISLOWER") Then 35 | F.ReturnText("MIDDLE") 36 | Endif 37 | EndIf 38 | F.ReturnText("LAST") 39 | EndSub 40 | Sub TEST_A_LOWER_C 41 | If F.Get("A") < F.Get("C") Then 42 | F.Set("ISLOWER", "True") 43 | EndIf 44 | EndSub 45 | Sub TEST_B_LOWER_C 46 | If F.Get("B") < F.Get("C") Then 47 | F.Set("ISLOWER", "True") 48 | EndIf 49 | EndSub 50 | 51 | 52 | ' Main function (calls other test functions, but is not recursive itself) 53 | F.Start = MAIN 54 | F.Function("MAIN", "L:") 55 | Sub MAIN 56 | ' normal use of global variable 57 | TOTAL = F.Call6("SUM6", 6, 3, 1, 4, 2, 5) 58 | Assert.Equal(TOTAL,21, "SUM6") 59 | 60 | ' use of local variable 61 | F.Set("L", F.Call3("LOWEST", 4,7,9)) 62 | Assert.Equal(F.Get("L"), "FIRST", "1") 63 | Assert.Equal(F.Call1("LOWEST", 5), "MIDDLE", "2") 64 | Assert.Equal(F.Call2("LOWEST", 5,7), "LAST", "3") 65 | 66 | ' TextWindow.WriteLine("main done") 67 | EndSub 68 | 69 | ' fire up the MAIN itself 70 | F.Call0("MAIN") 71 | Program.Delay(10000) 72 | -------------------------------------------------------------------------------- /Examples/GraphicsAndSounds.sb: -------------------------------------------------------------------------------- 1 | ' This example uses graphics and sound resources that must be already 2 | ' present on the EV3 in order to access them from the program. 3 | ' In this chase, a bitmap file (yamyam.rgf) and a sound file (emerald.rsf) 4 | ' are expected to exist in a sub-folder "GraphicsAndSounds' inside the 5 | ' "prjs" folder (you can create such a folder and transfer the files from the examples 6 | ' to the EV3 with the EV3Explorer. Contrary to the Small Basic convention, 7 | ' filenames for the EV3 are case-sensitive (because it is a Linux file system). 8 | ' 9 | ' As long as the EV3 explorer does not support file format conversion, you 10 | ' will probably still need the standard lego software to create you own sounds 11 | ' and bitmaps. 12 | 13 | 14 | LCD.Clear() 15 | LCD.BmpFile(1, 40,10, "GraphicsAndSounds/yamyam") 16 | 17 | Speaker.Play(100, "GraphicsAndSounds/emerald") 18 | 19 | Program.Delay(1000000) 20 | -------------------------------------------------------------------------------- /Examples/GraphicsAndSounds/emerald.rsf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/c0pperdragon/EV3Basic/762f3638324f66a0ee6d4fb0f9e095683b742e4c/Examples/GraphicsAndSounds/emerald.rsf -------------------------------------------------------------------------------- /Examples/GraphicsAndSounds/yamyam.rgf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/c0pperdragon/EV3Basic/762f3638324f66a0ee6d4fb0f9e095683b742e4c/Examples/GraphicsAndSounds/yamyam.rgf -------------------------------------------------------------------------------- /Examples/HelloWorld.sb: -------------------------------------------------------------------------------- 1 | LCD.Clear() 2 | LCD.Write(20,40,"Hello World") 3 | LCD.Write(20,60,"my name is") 4 | LCD.Write(20,80,EV3.Brickname) 5 | Program.Delay(10000) 6 | -------------------------------------------------------------------------------- /Examples/I2CRegisters.sb: -------------------------------------------------------------------------------- 1 | ' simple commucation with a I2C slave providing register access 2 | port = 1 ' where slave is connected 3 | address = 99 ' I2C address of the slave 4 | 5 | Sensor.WriteI2CRegister(port,address,2,105) 6 | Sensor.WriteI2CRegister(port,address,3,48) 7 | Sensor.WriteI2CRegister(port,address,4,12) 8 | W[0] = 15 9 | W[1] = 16 10 | W[2] = 17 11 | Sensor.WriteI2CRegisters(port,address,5,3,w) 12 | 13 | LCD.Clear() 14 | R = Sensor.ReadI2CRegisters(port,address,0,5) 15 | For reg=0 To 4 16 | LCD.Write(0,reg*16, reg+": "+R[reg]) 17 | EndFor 18 | For reg=5 To 7 19 | LCD.Write(0,reg*16, reg+": "+Sensor.ReadI2CRegister(port,address,reg)) 20 | EndFor 21 | 22 | Program.Delay(10000) 23 | 24 | -------------------------------------------------------------------------------- /Examples/MailboxReceive.sb: -------------------------------------------------------------------------------- 1 | ' This example create a mailbox named "Box" and waits for messages 2 | ' arrive which are then written to the LCD. 3 | ' This brick should be named "Bob" so it will work with the send example. 4 | 5 | id = Mailbox.Create("Box") 6 | While "True" 7 | msg = Mailbox.Receive(id) 8 | LCD.Clear() 9 | LCD.Write(0,40,msg) 10 | EndWhile 11 | -------------------------------------------------------------------------------- /Examples/MailboxSend.sb: -------------------------------------------------------------------------------- 1 | ' This example tries to send a string message to the brick named "Bob". 2 | ' The name of this brick does not matter, but it would follow the tradition 3 | ' to name it "Alice". 4 | 5 | Mailbox.Connect("Bob") ' try to connect to Bob in order to send a message 6 | 7 | Mailbox.Send("Bob", "Box", "Hi!") 8 | Program.Delay(1000) 9 | Mailbox.Send("Bob", "Box", "Goodbye.") 10 | Program.Delay(1000) 11 | 12 | -------------------------------------------------------------------------------- /Examples/Melody.sb: -------------------------------------------------------------------------------- 1 | V = 30 2 | T = 380 3 | 4 | Speaker.Tone(V, 262, T) 5 | Speaker.Wait() 6 | Speaker.Note(V, "C4", T) 7 | While Speaker.IsBusy() 8 | Program.Delay(2) 9 | endwhile 10 | Speaker.Note(V, "E4", T) 11 | Speaker.Wait() 12 | Speaker.Note(V, "G4", T) 13 | Speaker.Wait() 14 | Speaker.Note(V, "G4", T) 15 | Speaker.Wait() 16 | Program.Delay(T) 17 | Speaker.Note(V, "G4", T) 18 | Speaker.Wait() 19 | Speaker.Note(V, "G4", T) 20 | Speaker.Wait() 21 | Program.Delay(T) 22 | Speaker.Note(V, "E4", T) 23 | Speaker.Wait() 24 | Speaker.Note(V, "E4", T) 25 | Speaker.Wait() 26 | 27 | -------------------------------------------------------------------------------- /Examples/MotorCount.sb: -------------------------------------------------------------------------------- 1 | ' Example: Read motor position while motor is moving 2 | 3 | m = "A" 4 | samples = 178 5 | positions = Vector.Init(samples,0) ' list of positions 6 | times = Vector.Init(samples,0) ' time-stamps of samples 7 | 8 | ' start motor 9 | Motor.ResetCount(m) 10 | Motor.SchedulePower(m, 100, 0,110,0, "True") 11 | 12 | ' take samples fast 13 | start = EV3.Time 14 | For i=0 To samples-1 15 | ' wait for the correct sample time 16 | now = EV3.Time - start 17 | While now < i 18 | now = EV3.Time - start 19 | EndWhile 20 | ' take a motor position sample 21 | positions[i] = Motor.GetCount(m) 22 | times[i] = now 23 | Endfor 24 | 25 | ' show collected data 26 | LCD.Clear() 27 | For i=0 To samples-1 28 | LCD.Pixel(1,i,positions[i]) 29 | LCD.Pixel(1,i,128-times[i]) 30 | endfor 31 | 32 | Program.Delay(100000) -------------------------------------------------------------------------------- /Examples/MotorInvert.sb: -------------------------------------------------------------------------------- 1 | ' Do some motor movements and measurements, but 2 | ' one of the motors is mounted inverted. 3 | ' This should not bother the rest of the program - 4 | ' even the speed and count values are adjusted. 5 | Motor.Invert("A") 6 | 7 | LCD.Clear() 8 | Motor.Start("AB", 50) 9 | for i=0 to 7 10 | LCD.Write( 0,i*16, Motor.GetSpeed("A") + ":" + Motor.GetCount("A")) 11 | LCD.Write(100,i*16, Motor.GetSpeed("B") + ":" + Motor.GetCount("B")) 12 | Program.Delay(200) 13 | endfor 14 | Motor.Stop("AB", "False") 15 | 16 | Program.Delay(3000) 17 | 18 | LCD.Clear() 19 | Motor.StartSteer("AB", 70, -25) 20 | for i=0 to 7 21 | LCD.Write( 0,i*16, Motor.GetSpeed("A") + ":" + Motor.GetCount("A")) 22 | LCD.Write(100,i*16, Motor.GetSpeed("B") + ":" + Motor.GetCount("B")) 23 | Program.Delay(200) 24 | endfor 25 | Motor.Stop("AB", "False") 26 | 27 | Program.Delay(3000) 28 | -------------------------------------------------------------------------------- /Examples/MotorSteer.sb: -------------------------------------------------------------------------------- 1 | ' do some demonstration of the steer commands and then do the whole thing 2 | ' again but with motor A inverted 3 | For i=1 To 2 4 | Motor.MoveSteer("AB",70,-25, 1000,"True") 5 | Motor.MoveSteer("AB",70,25, 1000,"True") 6 | Program.Delay(1000) 7 | Motor.ScheduleSteer("AB",100,75,1000,"false") 8 | Program.Delay(2000) 9 | Motor.StartSteer("AB",50,-25) 10 | Program.Delay(2000) 11 | Motor.Stop("AB", "True") 12 | Program.Delay(2000) 13 | Motor.Invert("A") 14 | EndFor 15 | Program.End() 16 | -------------------------------------------------------------------------------- /Examples/MotorSynchronize.sb: -------------------------------------------------------------------------------- 1 | Motor.ScheduleSync("AB",-100,70,500,"false") 2 | Program.Delay(1000) 3 | Motor.StartSync("AB",100,-50) 4 | Program.Delay(1000) 5 | Motor.SchedulePower("A", 100, 0,500,0, "true") 6 | Program.Delay(1000) 7 | Motor.StartPower("AB", -100) 8 | Program.Delay(1000) 9 | Motor.Schedule("B", -100, 0,500,0, "false") 10 | Program.Delay(1000) 11 | Motor.MoveSync("AB", 70, 50, 500, "true") 12 | Program.Delay(1000) 13 | -------------------------------------------------------------------------------- /Examples/MovingCircle.sb: -------------------------------------------------------------------------------- 1 | 2 | X = 80 3 | Y = 64 4 | 5 | While "True" 6 | 7 | k = Buttons.Current 8 | If Text.IsSubText("L",K) then 9 | X = X-1 10 | ElseIf Text.IsSubText("R",K) then 11 | X = X+1 12 | ElseIf Text.IsSubText("U",K) then 13 | Y= Y-1 14 | ElseIf Text.IsSubText("D",K) then 15 | Y= Y+1 16 | ElseIf Text.IsSubText("E",K) then 17 | Program.End() 18 | endif 19 | 20 | LCD.StopUpdate() 21 | LCD.Clear() 22 | LCD.Text(1, 0,0, 1, "Use directional buttons ...") 23 | LCD.FillCircle(1, X,Y, 20) 24 | LCD.Update() 25 | 26 | Program.Delay(10) 27 | 28 | EndWhile 29 | -------------------------------------------------------------------------------- /Examples/Recursion.sb: -------------------------------------------------------------------------------- 1 | ' Simple function call demonstration with recursion, computing fibonacci numbers 2 | F.Start = FIBO 3 | F.Function("FIBO", "N") 4 | Sub FIBO 5 | If F.Get("N")<2 Then 6 | F.ReturnNumber(1) 7 | Else 8 | F.ReturnNumber(F.Call1("FIBO",F.Get("N")-2) + F.Call1("FIBO", F.Get("N")-1)) 9 | Endif 10 | EndSub 11 | 12 | Assert.Equal(F.Call1("FIBO", 6), 13, "incorrect result") 13 | Program.Delay(10000) 14 | -------------------------------------------------------------------------------- /Examples/SensorInfo.sb: -------------------------------------------------------------------------------- 1 | 2 | selectmode = 0 3 | Sensor.SetMode(1, selectmode) 4 | 5 | While "True" 6 | LCD.StopUpdate() 7 | LCD.Clear() 8 | For i=1 To 4 9 | name = Sensor.GetName(i) 10 | type = Sensor.GetType(i) 11 | mode = Sensor.GetMode(i) 12 | ready = Sensor.IsBusy(i) 13 | val = Sensor.ReadPercent(i) 14 | LCD.Text(1, 0,32*i-32, 1, name+" "+type+":"+mode) 15 | LCD.Text(1, 16,32*i-16, 1, val+" "+ready) 16 | endfor 17 | LCD.Update() 18 | Program.Delay(200) 19 | 20 | click = Buttons.GetClicks() 21 | If Text.IsSubText(click, "U") then 22 | selectmode = selectmode+1 23 | Sensor.SetMode(1, selectmode) 24 | ElseIf Text.IsSubText(click,"D") then 25 | selectmode = selectmode-1 26 | Sensor.SetMode(1, selectmode) 27 | ElseIf Text.IsSubText(click,"E") then 28 | Sensor.SetMode(1, selectmode) 29 | endif 30 | EndWhile 31 | -------------------------------------------------------------------------------- /Examples/SensorReading.sb: -------------------------------------------------------------------------------- 1 | selectmode = 0 2 | Sensor.SetMode(1, selectmode) 3 | 4 | 5 | While "True" 6 | LCD.StopUpdate() 7 | LCD.Clear() 8 | LCD.Write(0,0, Sensor.GetName(1)) 9 | LCD.Write(0,16, "MODE: "+Sensor.GetType(1)+":"+Sensor.GetMode(1)+" ("+selectmode+")") 10 | LCD.Write(0,32, "PERCENT: "+ Sensor.ReadPercent(1)) 11 | raw = Sensor.ReadRaw(1,8) 12 | For i=0 To 3 13 | LCD.Write(0,64+i*16, "RAW"+i+":"+raw[i]) 14 | endfor 15 | For i=4 To 7 16 | LCD.Write(80,64+(i-4)*16, "RAW"+i+":"+raw[i]) 17 | endfor 18 | LCD.Update() 19 | 20 | Program.Delay(200) 21 | 22 | click = Buttons.GetClicks() 23 | If Text.IsSubText(click, "U") then 24 | selectmode = selectmode+1 25 | Sensor.SetMode(1, selectmode) 26 | ElseIf Text.IsSubText(click,"D") then 27 | selectmode = selectmode-1 28 | Sensor.SetMode(1, selectmode) 29 | ElseIf Text.IsSubText(click,"E") then 30 | Sensor.SetMode(1, selectmode) 31 | endif 32 | 33 | 34 | EndWhile 35 | -------------------------------------------------------------------------------- /Examples/Threads.sb: -------------------------------------------------------------------------------- 1 | ' Small program to demonstate the use of threads 2 | ' The program will blink the device LED while at the 3 | ' same time increasing 4 seperate tick counters in a 4 | ' different speed. ' 5 | ' Writing the values of the counters to 6 | ' the display is done with one central Sub which gets 7 | ' called from the various ticker threads. 8 | ' To avoid mangling up the display, this Sub uses at 9 | ' mutex to protect the critical section. 10 | 11 | ' Set up tick counters 12 | ticks = Vector.Init(4,0) 13 | 14 | ' Create the mutex construct for future use 15 | mutex = Thread.CreateMutex() 16 | 17 | ' Subroutine to update the screen. Because it will be 18 | ' called in different threads these could conflict. 19 | ' To make sure only one thread can access the screen at 20 | ' the same time, the critical section must be protected 21 | ' by using a mutex. 22 | Sub SHOW 23 | ' Enter the critical section 24 | Thread.Lock(mutex) 25 | 26 | LCD.StopUpdate() 27 | LCD.Clear() 28 | For i=0 to 3 29 | LCD.Text(1, 20,10+25*i, 2,"Tick"+ticks[i]) 30 | Endfor 31 | LCD.Update() 32 | 33 | ' Leave the critical section 34 | Thread.Unlock(mutex) 35 | EndSub 36 | 37 | 38 | ' Fire up all threads for concurrent runs 39 | Thread.Run = BLINKER 40 | Thread.Run = TICK0 41 | Thread.Run = TICK1 42 | Thread.Run = TICK2 43 | TICK3() ' use main thread for one of the tickers 44 | 45 | Sub BLINKER 46 | While "true" 47 | EV3.SetLEDColor("ORANGE","NORMAL") 48 | Program.Delay(500) 49 | EV3.SetLEDColor("OFF","NORMAL") 50 | Program.Delay(500) 51 | EndWhile 52 | EndSub 53 | 54 | Sub TICK0 55 | While "true" 56 | ticks[0] = ticks[0]+1 57 | SHOW() 58 | Program.Delay(750) 59 | EndWhile 60 | EndSub 61 | 62 | Sub TICK1 63 | While "true" 64 | ticks[1] = ticks[1]+1 65 | SHOW() 66 | Program.Delay(1000) 67 | EndWhile 68 | EndSub 69 | 70 | Sub TICK2 71 | While "true" 72 | ticks[2] = ticks[2]+1 73 | SHOW() 74 | Program.Delay(1200) 75 | EndWhile 76 | EndSub 77 | 78 | Sub TICK3 79 | While "true" 80 | ticks[3] = ticks[3]+1 81 | SHOW() 82 | Program.Delay(1500) 83 | EndWhile 84 | EndSub 85 | -------------------------------------------------------------------------------- /Examples/TimeMeasurement.sb: -------------------------------------------------------------------------------- 1 | 2 | 3 | For i=1 To 100000 4 | LCD.StopUpdate() 5 | LCD.Clear() 6 | LCD.Text(1, 20,20, 1, "Time since start") 7 | LCD.Text(1, 20,40, 1, EV3.Time+" ms") 8 | LCD.Update() 9 | Program.Delay(100) 10 | EndFor 11 | -------------------------------------------------------------------------------- /Examples/TouchSensorTest.sb: -------------------------------------------------------------------------------- 1 | 2 | While "True" 3 | LCD.StopUpdate() 4 | LCD.Clear() 5 | LCD.Text(1, 0,0, 1, "Plug touch sensors to") 6 | LCD.Text(1, 0,12, 1, "various ports and ") 7 | LCD.Text(1, 0,24, 1, "press them...") 8 | 9 | For s=1 To 4 10 | P = Sensor.ReadPercent(s) 11 | x = s*40 - 30 12 | y = 60 13 | If P=100 Then 14 | LCD.FillRect(1,x,y, 30,30) 15 | LCD.Text(1,x+2,y+10, 1, P) 16 | else 17 | LCD.Rect(1,x,y,30,30) 18 | LCD.Text(1,x+10,y+10, 1, P) 19 | Endif 20 | endfor 21 | LCD.Update() 22 | 23 | Program.Delay(100) 24 | EndWhile 25 | -------------------------------------------------------------------------------- /Examples/TowersOfHanoi.sb: -------------------------------------------------------------------------------- 1 | ' small demonstration for recursive programming 2 | ' solve and visualize the old "towers of hanoi" problem. 3 | 4 | tower[0] = "JIHGFEDCBA" 5 | tower[1] = "" 6 | tower[2] = "" 7 | draw() 8 | 9 | a = 0 10 | b = 2 11 | n = 10 12 | move() 13 | Program.Delay(1000000) 14 | 15 | ' moves n pieces from tower[a] to tower[b] 16 | Sub move 17 | If n=1 Then 18 | move1() 19 | Elseif n>1 Then 20 | n = n-1 ' move n-1 pieces to temporary tower 21 | b = 3-a-b 22 | move() 23 | b = 3-a-b ' restore b 24 | move1() ' move the nth piece to destination 25 | a = 3-a-b 26 | move() ' move n-1 pieces from temporary tower to destination 27 | a = 3-a-b ' restore a 28 | n=n+1 ' restore n 29 | EndIf 30 | EndSub 31 | 32 | ' move top piece from tower[a] to tower[b] 33 | Sub move1 34 | Program.Delay(1000) 35 | l = Text.GetLength(tower[a]) 36 | newb = tower[b] + Text.GetSubText(tower[a],l,1) 37 | tower[b] = newb 38 | tower[a] = Text.GetSubText(tower[a], 1,l-1) 39 | draw() 40 | EndSub 41 | 42 | ' draw the current state of the towers 43 | Sub draw 44 | LCD.StopUpdate() 45 | LCD.Clear() 46 | For i=0 To 7 47 | For j=1 To Text.GetLength(tower[i]) 48 | w = 10+4*(Text.GetCharacterCode(Text.GetSubText(tower[i],j,1))-64) 49 | LCD.FillRect(1, i*60+30-w/2, 126-j*11, w,10) 50 | EndFor 51 | EndFor 52 | LCD.Update() 53 | EndSub 54 | 55 | -------------------------------------------------------------------------------- /Examples/TwoMotorMovement.sb: -------------------------------------------------------------------------------- 1 | ' create a coordinate motor movement where 2 | ' motor A has linear increasing position and 3 | ' motor B moves in a sine wave 4 | 5 | Y_PREV = 0 ' memorize position of motor B 6 | 7 | For X=1 To 3600 ' move steps of single degrees 8 | Y = 50*Math.Sin(X/180*Math.PI) ' calculate Y dependent of X 9 | Y = Math.Round(Y) ' rounding (motor can only go to integer values) 10 | 11 | Y_INC = Y - Y_PREV ' calculate the distance from current to new position 12 | Y_PREV = Y ' memorize the new position for next iteration 13 | 14 | Motor.SchedulePower("A",30,0,1,0,"true") ' move A by one degree 15 | 16 | If Y_INC>0 Then ' move motor B either forward 17 | Motor.SchedulePower("B",30,0,Y_INC,0,"true") 18 | Else ' or backwards 19 | Motor.SchedulePower("B",-30,0,Y_INC,0,"true") 20 | EndIf 21 | 22 | Motor.Wait("AB") ' wait until both motors have reached the position 23 | EndFor 24 | -------------------------------------------------------------------------------- /Examples/VectorDemo.sb: -------------------------------------------------------------------------------- 1 | 2 | ' ----------- VECTOR OPERATIONS ---------------- 3 | 4 | LCD.Clear() 5 | LCD.Text(1, 0,0, 1,"Vector operations") 6 | 7 | A = Vector.Data(5, " 13 -8 ") ' create vector with 5 elements, two given 8 | A[4] = 4 ' add some data 9 | LCD.Text(1, 0,24,0, "A: ") 10 | For i=0 To 4 11 | LCD.Text(1, 30+20*i,24, 1, A[i]) 12 | EndFor 13 | 14 | ' add 7 to every element of V and store in X 15 | B = Vector.Init(5, 7) ' create a vector with all 7s 16 | LCD.Text(1, 0,36, 1," + ") 17 | For i=0 To 4 18 | LCD.Text(1, 30+20*i,36, 1, B[i]) 19 | EndFor 20 | 21 | ' add these two vectors number-wise 22 | X = Vector.Add(5, A,B) 23 | LCD.Text(1, 0,48, 1,"X: ") 24 | For i=0 To 4 25 | LCD.Text(1, 30+20*i,48, 1, X[i]) 26 | EndFor 27 | 28 | ' compute the scalar product of A and X and store in vector Y 29 | ' (it is allowed to use same array as source and destination of operations) 30 | Y = A 31 | Y = Vector.Multiply(1,1,5, Y,X) 32 | 33 | LCD.Text(1, 10,72, 1,"scalar A*X: "+Y[0]) 34 | 35 | Buttons.Flush() 36 | Buttons.Wait() 37 | 38 | ' ---------- MATRIX MULTIPLICATION ---------- 39 | 40 | LCD.Clear() 41 | LCD.Text(1,0,0, 1,"Multiply") 42 | LCD.Text(1,0,10, 1,"matrizes") 43 | 44 | N = 4 45 | M = 3 46 | K = 2 47 | 48 | ' Define a 4 row, 2 column matrix. 49 | A = Vector.Data(4*2," 2 -1 1 3 1 2 -3 1 ") 50 | For I=0 To N-1 51 | For H=0 To K-1 52 | LCD.Text(1, 10+30*H,60+12*I, 1, A[K*I+H]) 53 | EndFor 54 | EndFor 55 | 56 | ' Define a 2 rows, 3 column matrix in one line: 57 | B = Vector.Data(2*3, "3 -1 4 3 2 -2 unused trailing 0 0 4") 58 | For H=0 To K-1 59 | For J=0 To M-1 60 | LCD.Text(1, 80+30*J,20+12*H, 1, B[M*H+J]) 61 | EndFor 62 | EndFor 63 | 64 | ' The resulting matrix will have 4 rows, 3 columns. 65 | C = Vector.Multiply(N,M,K, A,B) 66 | 67 | For I=0 To N-1 68 | For J=0 To M-1 69 | LCD.Text(1, 80+30*J,60+12*I, 1, C[M*I+J]) 70 | EndFor 71 | EndFor 72 | 73 | Buttons.Flush() 74 | Buttons.Wait() 75 | 76 | ' ----------------- SORT VECTOR ------------- 77 | 78 | LCD.Clear() 79 | LCD.Text(1,0,0,1, "Sort 60 numbers") 80 | 81 | X = Vector.Init(57,0) 82 | For I=0 To 57-1 83 | X[i] = Math.GetRandomNumber(1099)-99 ' -99 - 999 84 | EndFor 85 | 86 | ' Sort 60 elements. Since there are too few numbers in X, 0-values will be inserted. 87 | Y = Vector.Sort(60,X) 88 | 89 | For I=0 To 12-1 90 | For j=0 To 5-1 91 | LCD.Text(1, 36*j, 9+10*i, 1, Y[i*5+j]) 92 | endfor 93 | EndFor 94 | 95 | Buttons.Flush() 96 | Buttons.Wait() 97 | -------------------------------------------------------------------------------- /LMSAssembler/AssemblerException.cs: -------------------------------------------------------------------------------- 1 | /* EV3-Basic: A basic compiler to target the Lego EV3 brick 2 | Copyright (C) 2015 Reinhard Grafl 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Text; 21 | 22 | namespace LMSAssembler 23 | { 24 | class AssemblerException : Exception 25 | { 26 | public AssemblerException (String message) : base(message) 27 | { } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LMSAssembler/DataArea.cs: -------------------------------------------------------------------------------- 1 | /* EV3-Basic: A basic compiler to target the Lego EV3 brick 2 | Copyright (C) 2015 Reinhard Grafl 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Text; 21 | 22 | namespace LMSAssembler 23 | { 24 | // specifies one local or global data element 25 | public class DataElement 26 | { 27 | public readonly String name; 28 | public readonly int position; 29 | public readonly DataType datatype; 30 | 31 | public DataElement(String n, int p, DataType dt) 32 | { 33 | name = n; 34 | position = p; 35 | datatype = dt; 36 | } 37 | public override string ToString() 38 | { 39 | return position + " " + name + " " + datatype; 40 | } 41 | } 42 | 43 | // one continous space of data elements. 44 | // can be either global or a local data area for a thread or a subroutine 45 | public class DataArea 46 | { 47 | private Dictionary elements; 48 | private int endofarea; // total bytes already in use 49 | bool haveNonParameters; 50 | 51 | public DataArea() 52 | { 53 | elements = new Dictionary(); 54 | endofarea = 0; 55 | haveNonParameters = false; 56 | } 57 | 58 | public void Add(String name, int length, int number, DataType datatype, bool isParameter) 59 | { 60 | if (elements.ContainsKey(name)) 61 | { 62 | throw new AssemblerException("Identifier " + name + " already in use"); 63 | } 64 | 65 | if (!isParameter) 66 | { 67 | haveNonParameters = true; 68 | } 69 | else if (haveNonParameters) 70 | { 71 | throw new AssemblerException("Can not place IN,OUT,IO elements after DATA elements"); 72 | } 73 | 74 | while (endofarea%length != 0) // check if alignment fits 75 | { 76 | if (isParameter) // parameters must never be padded 77 | { 78 | throw new AssemblerException("Can not insert padding for propper alignment. Try to reorder the IO parameters that no padding is necessary"); 79 | } 80 | endofarea++; 81 | } 82 | 83 | elements[name] = new DataElement(name, endofarea, datatype); 84 | endofarea += length*number; 85 | } 86 | 87 | public int TotalBytes() 88 | { 89 | return endofarea; 90 | } 91 | 92 | public DataElement Get(String name) 93 | { 94 | if (!elements.ContainsKey(name)) 95 | { 96 | return null; 97 | } 98 | return elements[name]; 99 | } 100 | 101 | public void print() 102 | { 103 | foreach (DataElement el in elements.Values) 104 | { 105 | Console.WriteLine(el); 106 | } 107 | } 108 | } 109 | 110 | 111 | 112 | } 113 | -------------------------------------------------------------------------------- /LMSAssembler/DataReader.cs: -------------------------------------------------------------------------------- 1 | /* EV3-Basic: A basic compiler to target the Lego EV3 brick 2 | Copyright (C) 2015 Reinhard Grafl 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Text; 21 | using System.IO; 22 | 23 | namespace LMSAssembler 24 | { 25 | class DataReader 26 | { 27 | 28 | public static int Read32(Stream stream, ref int readposition) 29 | { 30 | int b0 = stream.ReadByte() & 0xff; 31 | int b1 = stream.ReadByte() & 0xff; 32 | int b2 = stream.ReadByte() & 0xff; 33 | int b3 = stream.ReadByte() & 0xff; 34 | readposition += 4; 35 | return b0 | (b1<<8) | (b2<<16) | (b3<<24); 36 | } 37 | 38 | public static int Read16(Stream stream, ref int readposition) 39 | { 40 | int b0 = stream.ReadByte() & 0xff; 41 | int b1 = stream.ReadByte() & 0xff; 42 | readposition += 2; 43 | return (short) (b0 | (b1 << 8)); 44 | } 45 | 46 | public static int Read8(Stream stream, ref int readposition) 47 | { 48 | int b0 = stream.ReadByte() & 0xff; 49 | readposition += 1; 50 | return (sbyte) b0; 51 | } 52 | 53 | } 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /LMSAssembler/DataWriter.cs: -------------------------------------------------------------------------------- 1 | /* EV3-Basic: A basic compiler to target the Lego EV3 brick 2 | Copyright (C) 2015 Reinhard Grafl 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Text; 21 | using System.IO; 22 | 23 | namespace LMSAssembler 24 | { 25 | public class DataWriter 26 | { 27 | 28 | public static void Write32(Stream stream, int value) 29 | { 30 | stream.WriteByte((byte)(value & 0xff)); 31 | stream.WriteByte((byte)((value >> 8) & 0xff)); 32 | stream.WriteByte((byte)((value >> 16) & 0xff)); 33 | stream.WriteByte((byte)((value >> 24) & 0xff)); 34 | } 35 | 36 | public static void Write16(Stream stream, int value) 37 | { 38 | stream.WriteByte((byte)(value & 0xff)); 39 | stream.WriteByte((byte)((value >> 8) & 0xff)); 40 | } 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /LMSAssembler/LMSAssembler.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {DB6E87AD-6CB4-401A-925B-7E40F7CBF042} 8 | Library 9 | Properties 10 | LMSAssembler 11 | LMSAssembler 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | false 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | True 54 | True 55 | Resources.resx 56 | 57 | 58 | 59 | 60 | 61 | 62 | ResXFileCodeGenerator 63 | Resources.Designer.cs 64 | 65 | 66 | 67 | 68 | 69 | 70 | 77 | -------------------------------------------------------------------------------- /LMSAssembler/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LMSAssembler")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LMSAssembler")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("45ec7a94-f29f-4af8-9feb-63ac617a234d")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /LMSAssembler/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace LMSAssembler.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LMSAssembler.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to 00 ERROR 65 | ///01 NOP 66 | ///02 PROGRAM_STOP 16 67 | ///03 PROGRAM_START 16 32 32 8 68 | ///04 OBJECT_STOP T 69 | ///05 OBJECT_START T 70 | ///06 OBJECT_TRIG T 71 | ///07 OBJECT_WAIT T 72 | ///08 RETURN 73 | ///// 09 CALL 74 | ///0A OBJECT_END 75 | ///0B SLEEP 76 | /// 77 | ///0C00 PROGRAM_INFO OBJ_STOP 16 16 78 | ///0C04 PROGRAM_INFO OBJ_START 16 16 79 | ///0C16 PROGRAM_INFO GET_STATUS 16 8* 80 | ///0C17 PROGRAM_INFO GET_SPEED 16 32* 81 | ///0C18 PROGRAM_INFO GET_PRGRESULT 16 8* 82 | ///// 0C19 PROGRAM_INFO SET_INSTR 83 | /// 84 | ///0D LABEL [rest of string was truncated]";. 85 | /// 86 | internal static string bytecodelist { 87 | get { 88 | return ResourceManager.GetString("bytecodelist", resourceCulture); 89 | } 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /LMSAssembler/VMCommand.cs: -------------------------------------------------------------------------------- 1 | /* EV3-Basic: A basic compiler to target the Lego EV3 brick 2 | Copyright (C) 2015 Reinhard Grafl 3 | 4 | This program is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program. If not, see . 16 | */ 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Text; 21 | 22 | namespace LMSAssembler 23 | { 24 | 25 | public class VMCommand 26 | { 27 | public readonly String name; 28 | public readonly byte[] opcode; 29 | 30 | public readonly DataType[] parameters; 31 | public readonly AccessType[] access; 32 | 33 | 34 | public VMCommand(String descriptor) 35 | { 36 | char[] delimiters = new char[] { '\t', ' ' }; 37 | String[] tokens = descriptor.Split(delimiters, StringSplitOptions.RemoveEmptyEntries); 38 | 39 | int pstart = 0; 40 | if (tokens[0].Length==2 && tokens.Length>=2) 41 | { 42 | opcode = new byte[] { (byte) Convert.ToInt32(tokens[0], 16) }; 43 | name = tokens[1]; 44 | pstart = 2; 45 | } 46 | else if (tokens[0].Length==4 && tokens.Length>=3) 47 | { 48 | opcode = new byte[] { (byte)Convert.ToInt32(tokens[0].Substring(0,2), 16) 49 | , (byte)Convert.ToInt32(tokens[0].Substring(2,2), 16) 50 | }; 51 | name = tokens[1] + " " + tokens[2]; 52 | pstart = 3; 53 | } 54 | else 55 | { 56 | throw new Exception("Can not decode definition list"); 57 | } 58 | 59 | int nump = tokens.Length - pstart; 60 | parameters = new DataType[nump]; 61 | access = new AccessType[nump]; 62 | for (int i = 0; i < nump; i++) 63 | { 64 | String t = tokens[pstart + i]; 65 | if (t.StartsWith("8")) 66 | { 67 | parameters[i] = DataType.I8; 68 | } 69 | else if (t.StartsWith("16")) 70 | { 71 | parameters[i] = DataType.I16; 72 | } 73 | else if (t.StartsWith("32")) 74 | { 75 | parameters[i] = DataType.I32; 76 | } 77 | else if (t.StartsWith("F")) 78 | { 79 | parameters[i] = DataType.F; 80 | } 81 | else if (t.StartsWith("?")) 82 | { 83 | parameters[i] = DataType.Unspecified; 84 | } 85 | else if (t.Equals("L")) 86 | { 87 | parameters[i] = DataType.Label; 88 | } 89 | else if (t.Equals("T")) 90 | { 91 | parameters[i] = DataType.VMThread; 92 | } 93 | else if (t.Equals("S")) 94 | { 95 | parameters[i] = DataType.VMSubcall; 96 | } 97 | else if (t.Equals("P")) 98 | { 99 | parameters[i] = DataType.ParameterCount; 100 | } 101 | else 102 | { 103 | throw new Exception("Can not read opcode descriptor: "+descriptor); 104 | } 105 | 106 | if (t.EndsWith("*")) 107 | { 108 | access[i] = AccessType.Write; 109 | } 110 | else if (t.EndsWith("+")) 111 | { 112 | access[i] = AccessType.ReadMany; 113 | } 114 | else 115 | { 116 | access[i] = AccessType.Read; 117 | } 118 | } 119 | } 120 | 121 | public override String ToString() 122 | { 123 | String s = BitConverter.ToString(opcode) + " "+ name; 124 | for (int i = 0; i < parameters.Length; i++) 125 | { 126 | s = s + " " + parameters[i] + access[i]; 127 | } 128 | return s; 129 | } 130 | } 131 | 132 | 133 | } 134 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EV3Basic 2 | A basic compiler to target the Lego Mindstorms EV3 intelligent brick. 3 | 4 | This programming language and development environment is intended as an easy way to use text based programming for the EV3. It was specifically designed to get things running quickly and should help novice programmers to get their first experience. 5 | 6 | 7 | ## Microsoft Small Basic Extension 8 | 9 | One convenient way to develop programs for the EV3 is to use Microsoft Small Basic (download is free of charge) together with the EV3 extension. With this you have an easy to use development environment where you can build and run programs that control the EV3 brick from your PC. 10 | 11 | ### Installation 12 | 13 | 1. Download and install Microsoft Small Basic from http://smallbasic.com/ (requires Microsoft Windows) 14 | 2. Download EV3BasicInstaller.msi from the current release and install the program into the same folder as Small Basic. 15 | 16 | ### Using Small Basic 17 | 18 | 1. Start Small Basic and begin writing your program. Use the intellisense documentation to learn about the various parts of the EV3 extension. 19 | 2. If you are a novice to programming, use the link "Beginning Small Basic" on the Small Basic homepage to learn about fundamental concepts and how to generally create programs. 20 | 3. Run your program directly from the Small Basic environment. When you access functions for the EV3 brick (Everything in EV3, LCD, Motor, Sensor, Buttons, Speaker), the program tries to access and control the EV3 brick via an USB connection. 21 | 22 | ### Tutorials 23 | 24 | There is a good website available with loads of additional help and info: http://ev3basic.com 25 | 26 | ## EV3 Explorer (with compiler) 27 | 28 | The EV3 Explorer can be used to view and organize the files that are currently stored on the EV3 brick. But most importantly it has a built-in compiler that can convert your Small Basic programs to a form that can be executed directly on the brick. 29 | 30 | ### Installation and Startup 31 | 32 | Since version 0.9, the EV3Explorer is automatically installed along with the EV3 extension. It can be started from the windows start menu EV3Basic/EV3Explorer. 33 | 34 | ### Use EV3Explorer 35 | 36 | The main window is divided in two parts. The left one shows the file system of the EV3, the right shows your local PC file system (both with navigation buttons on top). 37 | To transfer (and optionally compile) files, select one file in the right window and click one of the "Compile" or "Download" buttons. 38 | Most programs will compile to the EV3 without much problems as long as you do not use unsupported functions. But there are subtle differences for some language constructs which will cause compilation to fail with an error. 39 | 40 | ## Contribute 41 | 42 | If you want to contribute to this project, there are certain tasks where I would need help: 43 | 44 | * More testing of the Small Basic extension and the compiler 45 | * Proofreading the documentation in various languages 46 | * New translations: See the 'Translations' issue thread for more details on this. 47 | 48 | If you absolutely insist, you may also donate money to my paypal account that is linked 49 | to my email address (see below). 50 | 51 | ## Contact 52 | 53 | For questions, comments, bug reports and feature requests please contact: reinhard.grafl (at) aon.at 54 | or just open a new issue in the github issues section. 55 | 56 | -------------------------------------------------------------------------------- /SmallBasicEV3Extension/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("EV3Basic")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("EV3Basic")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("60bbf35c-4b20-4f1e-8753-e0b9028ff654")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SmallBasicEV3Extension/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34209 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SmallBasicEV3Extension.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SmallBasicEV3Extension.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /SmallBasicEV3Extension/SmallBasicEV3Extension.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {1AA9B6CA-3833-4012-89C9-5628BEBA1657} 8 | Library 9 | Properties 10 | SmallBasicEV3Extension 11 | SmallBasicEV3Extension 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | bin\Debug\SmallBasicEV3Extension.xml 25 | false 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | false 35 | bin\Release\SmallBasicEV3Extension.XML 36 | 37 | 38 | 39 | externals\SmallBasicLibrary.dll 40 | False 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | True 61 | True 62 | Resources.resx 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | {c3c8582b-f715-41f9-a565-14c6918a0105} 73 | EV3Communication 74 | False 75 | 76 | 77 | 78 | 79 | ResXFileCodeGenerator 80 | Resources.Designer.cs 81 | 82 | 83 | 84 | 91 | -------------------------------------------------------------------------------- /SmallBasicEV3Extension/externals/SmallBasicLibrary - V1.1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/c0pperdragon/EV3Basic/762f3638324f66a0ee6d4fb0f9e095683b742e4c/SmallBasicEV3Extension/externals/SmallBasicLibrary - V1.1.dll -------------------------------------------------------------------------------- /SmallBasicEV3Extension/externals/SmallBasicLibrary.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/c0pperdragon/EV3Basic/762f3638324f66a0ee6d4fb0f9e095683b742e4c/SmallBasicEV3Extension/externals/SmallBasicLibrary.dll -------------------------------------------------------------------------------- /native/nativecode: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/c0pperdragon/EV3Basic/762f3638324f66a0ee6d4fb0f9e095683b742e4c/native/nativecode -------------------------------------------------------------------------------- /native/nativecode.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | 7 | // Native code for features that can not be done with the lego-VM 8 | // The program is can be running as an independent thread communicating via stdin and stdout 9 | // (which is properly prepared to use named pipes by the VM-program). 10 | // It can also be running on a call-by-call basis, where the parameters are provided 11 | // as call arguments to main, an the result value is returned as exit code 12 | // 13 | // Currently supported commands: 14 | // tablelookup 15 | // extracts one byte from a potentially huge file and returns its 16 | // value as a decimal number on stdout 17 | 18 | #define MAXSEEK 2147483647 19 | 20 | int tablelookup(char* parameterstring) 21 | { 22 | char filename[1000]; 23 | float bytes_per_row; 24 | float row; 25 | float column; 26 | 27 | if (sscanf (parameterstring, "%s %f %f %f", filename, &bytes_per_row, &row, &column)!=4) 28 | { 29 | return 255; 30 | } 31 | 32 | if (bytes_per_row<1 || row<0 || column<0) 33 | { return 255; 34 | } 35 | 36 | int fd = open(filename, O_RDONLY); 37 | if (fd<0) 38 | { 39 | return 255; 40 | } 41 | 42 | unsigned long off = 43 | ((unsigned long int) bytes_per_row) * ((unsigned long int) row) 44 | + ((unsigned long int) column); 45 | while (off>0) 46 | { 47 | if (off <= MAXSEEK) 48 | { 49 | lseek(fd,off,SEEK_CUR); 50 | break; 51 | } 52 | else 53 | { 54 | lseek(fd,MAXSEEK,SEEK_CUR); 55 | off -= MAXSEEK; 56 | } 57 | } 58 | 59 | char value; 60 | int didread = read (fd, &value, 1); 61 | 62 | close(fd); 63 | 64 | if (didread!=1) 65 | { 66 | return 255; 67 | } 68 | 69 | return value; 70 | } 71 | 72 | int processcommand(char* buffer) 73 | { 74 | // dispatch commands according to their begin 75 | if (strstr(buffer, "tablelookup ") == buffer) // test if command begins with this 76 | { 77 | return tablelookup(buffer+12); 78 | } 79 | // unreconized commands are just answered with 255 80 | else 81 | { 82 | return 255; 83 | } 84 | 85 | } 86 | 87 | int main(int argc, char** argv) 88 | { 89 | char buffer[1000]; 90 | 91 | // when parameters are provided, it will work in direct call mode 92 | if (argc>1) 93 | { 94 | strcpy (buffer, argv[1]); 95 | int i; 96 | for (i=2; i param+result passing: 6424 16 | CALL TEST.NOOP S1 S2 + RETURN (with Strings!) 23226 17 | -------------------------------------------------------------------------------- /testsuite/ev3features/CPUConsumption.sb: -------------------------------------------------------------------------------- 1 | timeused = 0 2 | 3 | LCD.Clear() 4 | CALC() 5 | LCD.Text(1,0,30,1,"No threads: "+timeused+"ms") 6 | continuegently = "true" 7 | Thread.Run = GENT 8 | CALC() 9 | continuegently = "false" 10 | LCD.Text(1,0,45,1,"Gentle thread: "+timeused+"ms") 11 | Thread.Run = HOG 12 | CALC() 13 | LCD.Text(1,0,60,1,"Hog thread: "+timeused+"ms") 14 | 15 | Program.Delay(500000) 16 | 17 | 18 | ' simulate a bigger calculation 19 | Sub CALC 20 | start = EV3.Time 21 | For i=1 To 1000000 22 | endfor 23 | timeused = EV3.Time - start 24 | EndSub 25 | 26 | ' a nice thread that gives up every time-slice 27 | Sub GENT 28 | While continuegently 29 | Math.Cos(0.532) 30 | Thread.Yield() 31 | endwhile 32 | EndSub 33 | 34 | ' a thread completely hogging the CPU 35 | Sub HOG 36 | While "true" 37 | Math.Sin(2.4) 38 | endwhile 39 | EndSub 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /testsuite/ev3features/ConcurrentWaits.sb: -------------------------------------------------------------------------------- 1 | Thread.Run = t1 2 | t2() ' use main thread for T2 3 | 4 | ' the thread to control the motor A depending on sensor 1 5 | Sub t1 6 | x1=0 7 | While "True" 8 | Sensor.Wait(1) ' wait until ready (must not block other thread) 9 | If (Sensor.ReadPercent(1)>50) Then 10 | Motor.StartPower("A", 50) 11 | Program.Delay(1000) 12 | Motor.Stop("A", "true") 13 | EndIf 14 | 15 | ' give visual hint, that this thread is running 16 | x1=Math.Remainder(x1+1,2) 17 | If x1=0 then 18 | EV3.SetLEDColor("ORANGE","NORMAL") 19 | Else 20 | EV3.SetLEDColor("OFF","NORMAL") 21 | endif 22 | 23 | Program.Delay(100) 24 | EndWhile 25 | endsub 26 | 27 | ' the thread to control the motor B depending on sensor 2 28 | Sub t2 29 | While "True" 30 | Sensor.Wait(2) ' wait until ready (must not block other thread) 31 | If (Sensor.ReadPercent(2)>50) Then 32 | Motor.StartPower("B", 50) 33 | Program.Delay(1000) 34 | Motor.Stop("B","true") 35 | EndIf 36 | 37 | ' give acoustic hint, that this thread is running 38 | Speaker.Tone(5,440,100) 39 | 40 | Program.Delay(100) 41 | EndWhile 42 | EndSub 43 | 44 | -------------------------------------------------------------------------------- /testsuite/ev3features/FileAccess.sb: -------------------------------------------------------------------------------- 1 | 2 | LCD.Clear() 3 | 4 | F = EV3File.OpenWrite("testfile.txt") 5 | LCD.Write(0,0,"Write handle: "+F) 6 | EV3File.WriteLine(F, "dummy text") 7 | EV3File.WriteByte(F, 64) 8 | EV3File.WriteByte(F, 10) 9 | EV3File.Close(F) 10 | 11 | F = EV3File.OpenAppend("testfile.txt") 12 | LCD.Write(0,16,"Append handle: "+F) 13 | EV3File.WriteLine(F, "more text") 14 | EV3File.Close(F) 15 | 16 | F = EV3File.OpenRead("testfile.txt") 17 | LCD.Write(0,32,"Read handle: "+F) 18 | For I=1 To 5 19 | LCD.Write(0,32+16*i,i+": "+EV3File.ReadLine(F)) 20 | endfor 21 | EV3File.Close(F) 22 | 23 | LCD.Write(120,112,"Done") 24 | Program.Delay(10000) 25 | -------------------------------------------------------------------------------- /testsuite/ev3features/I2CMultiByte.sb: -------------------------------------------------------------------------------- 1 | send[0] = 47 2 | send[1] = 11 3 | send[2] = 8 4 | send[3] = 15 5 | 6 | rdlen = 10 7 | receive = Sensor.CommunicateI2C(1,4, 7, rdlen, send) 8 | 9 | LCD.Clear() 10 | For i=0 To rdlen-1 11 | LCD.Text(1, 0,i*12, 1, "r: "+receive[i]) 12 | EndFor 13 | 14 | Program.Delay(5000) 15 | 16 | -------------------------------------------------------------------------------- /testsuite/ev3features/IC2SendPulse.sb: -------------------------------------------------------------------------------- 1 | 2 | ZEROES = Vector.Init(31,0) 3 | numsend = 1 4 | 5 | While "True" 6 | X = Sensor.CommunicateI2C(1,0,numsend,1,ZEROES) 7 | 8 | k = Buttons.GetClicks() 9 | If Text.IsSubText(k,"U") and numsend<31 Then 10 | numsend = numsend+1 11 | ElseIf Text.IsSubText(k,"D") and numsend>0 then 12 | numsend = numsend-1 13 | endif 14 | 15 | LCD.Clear() 16 | LCD.Write(1,1, numsend) 17 | Program.Delay(100) 18 | 19 | EndWhile 20 | 21 | -------------------------------------------------------------------------------- /testsuite/ev3features/NativeCode.sb: -------------------------------------------------------------------------------- 1 | LCD.Clear() 2 | 3 | EV3.NativeCode("warm-up") 4 | 5 | START = EV3.Time 6 | For I=0 To 79 7 | R = EV3.NativeCode("bogus") 8 | EndFor 9 | END = EV3.Time 10 | 11 | LCD.Text (1,0,48,1, "R:" + R) 12 | LCD.Text (1,0,64,1, "Time: "+(END-START)+"ms") 13 | 14 | Program.Delay(10000) 15 | -------------------------------------------------------------------------------- /testsuite/ev3features/TableLookup.sb: -------------------------------------------------------------------------------- 1 | 'TextWindow.WriteLine("started...") 2 | LCD.Clear() 3 | 4 | EV3File.TableLookup("SD_Card/tables/table1.avi", 1,0,0) 5 | 6 | START = EV3.Time 7 | For I=0 To 79 8 | R[I] = EV3File.TableLookup("SD_Card/tables/table1.avi", 10000000, 10+I, 0) 9 | EndFor 10 | END = EV3.Time 11 | 12 | For I=0 To 79 13 | LCD.Text (1,Math.Remainder(I,8)*22,Math.Floor(I/8)*10,1, R[i]) 14 | EndFor 15 | LCD.Text (1,0,112,1, "Time: "+(END-START)+"ms") 16 | 17 | Program.Delay(10000) 18 | -------------------------------------------------------------------------------- /testsuite/ev3features/UARTSend.sb: -------------------------------------------------------------------------------- 1 | send[0] = 47 2 | send[1] = 11 3 | send[2] = 8 4 | send[3] = 15 5 | 6 | Sensor.SendUARTData(1,4,send) 7 | Program.Delay(5000) 8 | 9 | -------------------------------------------------------------------------------- /testsuite/floatparameter.lms: -------------------------------------------------------------------------------- 1 | 2 | vmthread MAIN 3 | DATAS txt 20 4 | 5 | INIT_BYTES txt 10 65 66 67 68 69 32 48 49 50 0 6 | 7 | DATAF x 8 | DATA16 x16 9 | 10 | MOVEF_F -13.1 x 11 | MOVEF_16 x x16 12 | 13 | UI_DRAW CLEAN 14 | UI_DRAW SELECT_FONT 1 15 | UI_DRAW TEXT 1 x16 40 txt 16 | UI_DRAW TEXT 1 31 50 txt 17 | UI_DRAW UPDATE 18 | 19 | DATA32 timer 20 | TIMER_WAIT 10000 timer 21 | TIMER_READY timer 22 | } 23 | -------------------------------------------------------------------------------- /testsuite/languagefeatures/ArrayTest.sb: -------------------------------------------------------------------------------- 1 | A[35] = 17 2 | B[7] = "world" 3 | B[2] = "hello" 4 | 5 | Assert.Equal(A[35], 17, "Retrieve float") 6 | Assert.Equal(A[3]+0, 0, "Non-existing float behaves like 0") 7 | 8 | Assert.Equal(B[2], "hello", "Retrieve string") 9 | Assert.Equal(B[7], "world", "Retrieve string 2") 10 | Assert.Equal(B[4], "", "Retrieve non-existing string") 11 | Assert.Equal(B[14], "","Retrieve non-existing string") 12 | 13 | C = A ' copy a whole float array 14 | Assert.Equal(C[35], 17, "Copied float array") 15 | 16 | D = B ' copy a whole string array 17 | Assert.Equal(D[7], "world", "After string array copy") 18 | Assert.Equal(D[4], "", "Empty in copy") 19 | D[6] = "something" 20 | Assert.Equal(D[7], "world", "Must not be destroyed by previous command") 21 | 22 | huge = "Extremely huge string that needs to be fit into ! " 23 | huge = huge+huge+huge+huge+huge+"." 24 | Assert.Equal(Text.GetLength(huge), 251, "string not correct") 25 | D[1] = huge 26 | Assert.Equal(huge,D[1], "Huge string in array") 27 | 28 | LCD.Clear() 29 | LCD.Text(1, 50,50, 1,"OK") 30 | Buttons.Wait() 31 | -------------------------------------------------------------------------------- /testsuite/languagefeatures/ConcurrentThreads.sb: -------------------------------------------------------------------------------- 1 | a=1 2 | Thread.Run = changer 3 | 4 | While "true" 5 | x = a 6 | x = x+a 7 | If x<>2 And x<>4 then 8 | TextWindow.WriteLine("Found miss-match") 9 | endif 10 | endwhile 11 | 12 | 13 | Sub changer 14 | While "True" 15 | A = 1 16 | A = 1 17 | A = 1 18 | A = 1 19 | A = 1 20 | A = 2 21 | A = 2 22 | A = 2 23 | A = 2 24 | A = 2 25 | endwhile 26 | endsub 27 | -------------------------------------------------------------------------------- /testsuite/languagefeatures/LargeMemory.sb: -------------------------------------------------------------------------------- 1 | ' Test program to check how much memory is available for variables 2 | 3 | SIZE = 1000000 4 | 5 | LCD.Clear() 6 | A = Vector.Init(SIZE, 4711) 7 | LCD.Text(1, 10,0, 1, "A["+(SIZE-1)+"] = " + A[SIZE-1]) 8 | B = Vector.Init(SIZE, 815) 9 | LCD.Text(1, 10,12, 1, "B["+(SIZE-1)+"] = " + B[SIZE-1]) 10 | C = Vector.Init(SIZE, 1111) 11 | LCD.Text(1, 10,24, 1, "C["+(SIZE-1)+"] = " + C[SIZE-1]) 12 | D = Vector.Init(SIZE, 2222) 13 | LCD.Text(1, 10,36, 1, "D["+(SIZE-1)+"] = " + D[SIZE-1]) 14 | E = Vector.Init(SIZE, 3333) 15 | LCD.Text(1, 10,48, 1, "E["+(SIZE-1)+"] = " + E[SIZE-1]) 16 | F = Vector.Init(SIZE, 4444) 17 | LCD.Text(1, 10,60, 1, "F["+(SIZE-1)+"] = " + F[SIZE-1]) 18 | G = Vector.Init(SIZE, 5555) 19 | LCD.Text(1, 10,72, 1, "G["+(SIZE-1)+"] = " + G[SIZE-1]) 20 | H = Vector.Init(SIZE, 666) 21 | LCD.Text(1, 10,84, 1, "H["+(SIZE-1)+"] = " + H[SIZE-1]) 22 | I = Vector.Init(SIZE, 1234) 23 | LCD.Text(1, 10,96, 1, "I["+(SIZE-1)+"] = " + I[SIZE-1]) 24 | J = Vector.Init(SIZE, 5678) 25 | LCD.Text(1, 10,108, 1, "J["+(SIZE-1)+"] = " + J[SIZE-1]) 26 | 27 | Buttons.Wait() 28 | -------------------------------------------------------------------------------- /testsuite/languagefeatures/Locking.sb: -------------------------------------------------------------------------------- 1 | ' create a mutex for thread synchronization 2 | M = Thread.CreateMutex() 3 | ' fire up 2 threads and use the main thread as a third 4 | Thread.Run = T1 5 | Thread.Run = T2 6 | T3() 7 | 8 | ' Many concurrent threads that want to access a shared resource 9 | ' in a random fashion 10 | Sub T1 11 | While "true" 12 | Program.Delay(Math.GetRandomNumber(10000)) 13 | BlinkAndBeep() 14 | endwhile 15 | EndSub 16 | 17 | Sub T2 18 | While "true" 19 | Program.Delay(Math.GetRandomNumber(10000)) 20 | BlinkAndBeep() 21 | endwhile 22 | EndSub 23 | 24 | Sub T3 25 | While "true" 26 | Program.Delay(Math.GetRandomNumber(10000)) 27 | BlinkAndBeep() 28 | endwhile 29 | EndSub 30 | 31 | ' A subroutine doing a 2-second long beep and blink patern 32 | ' Any thread may call this routine, but the individual runs must not 33 | ' be desturbed, so a mutex is used to allow only one thread into the 34 | ' critical section 35 | Sub BlinkAndBeep 36 | Thread.Lock(M) 37 | 38 | EV3.SetLEDColor("ORANGE", "NORMAL") 39 | Program.Delay(500) 40 | EV3.SetLEDColor("OFF", "NORMAL") 41 | Speaker.Note(15, "C4", 500) 42 | Program.Delay(500) 43 | EV3.SetLEDColor("RED", "NORMAL") 44 | Speaker.Note(15, "F4", 500) 45 | Program.Delay(500) 46 | EV3.SetLEDColor("OFF", "NORMAL") 47 | Program.Delay(500) 48 | 49 | Thread.Unlock(M) 50 | EndSub 51 | -------------------------------------------------------------------------------- /testsuite/languagefeatures/ManyThreads.sb: -------------------------------------------------------------------------------- 1 | I = 0 2 | LCD.Clear() 3 | 4 | Thread.Run = SUB1 5 | Program.Delay(200) 6 | Thread.Run = SUB1 7 | Thread.Run = SUB2 8 | Thread.Run = SUB3 9 | Thread.Run = SUB3 10 | 11 | Program.Delay(500000) 12 | 13 | Sub SUB1 14 | Thread.Run = SUB3 15 | Thread.Run = SUB3 16 | Thread.Run = SUB3 17 | EndSub 18 | 19 | Sub SUB2 20 | Thread.Run = SUB3 21 | Thread.Run = SUB3 22 | Thread.Run = SUB3 23 | EndSub 24 | 25 | Sub SUB3 26 | LCD.Text(1, 40,10*I, 1, (I+1)+". call") 27 | I= I+1 28 | Program.Delay(100) 29 | EndSub 30 | -------------------------------------------------------------------------------- /testsuite/languagefeatures/MathTest.sb: -------------------------------------------------------------------------------- 1 | ' Abs 2 | Assert.Equal(Math.Abs(-0.5),0.5, "Normal Abs") 3 | Assert.Equal(Math.Abs(0.5),0.5, "Abs already positive") 4 | Assert.Equal(Math.Abs(0.0),0.0, "Abs zero") 5 | 6 | ' ArcCos 7 | Assert.Near(Math.ArcCos(0.4), 1.1592794807274085998, "ArcCos 1") 8 | Assert.Near(Math.ArcCos(-0.8), 2.4980915447961545622, "ArcCos 2") 9 | 10 | ' ArcSin 11 | Assert.Near(Math.ArcSin(0.4), 0.41151684606748801, "ArcSin 1") 12 | Assert.Near(Math.ArcSin(-0.8), -0.9272952180016122, "ArcSin 2") 13 | 14 | ' ArcTan 15 | Assert.Near(Math.ArcTan(0.4), 0.380506377112364886, "ArcTan 1") 16 | Assert.Near(Math.ArcTan(-3.8), -1.3134726118238079, "ArcTan 2") 17 | 18 | ' Ceiling 19 | Assert.Equal(Math.Ceiling(0.4), 1, "Ceiling 1") 20 | Assert.Equal(Math.Ceiling(-0.4), 0, "Ceiling 2") 21 | Assert.Equal(Math.Ceiling(-1.0), -1, "Ceiling 3") 22 | Assert.Equal(Math.Ceiling(12312.5), 12313, "Ceiling 4") 23 | Assert.Equal(Math.Ceiling(-0.5), 0, "Avoid negative zero") 24 | 25 | ' Cos 26 | Assert.Near(Math.Cos(0.5), 0.8775825618903727161, "Cos 1") 27 | Assert.Near(Math.Cos(2.5), -0.8011436155469337148, "Cos 2") 28 | 29 | ' Floor 30 | Assert.Equal(Math.Floor(0.4), 0, "Floor 1") 31 | Assert.Equal(Math.Floor(-0.4), -1, "Floor 2") 32 | Assert.Equal(Math.Floor(-1.0), -1, "Floor 3") 33 | Assert.Equal(Math.Floor(12312.5), 12312, "Floor 4") 34 | 35 | ' GetDegrees 36 | Assert.Near(Math.GetDegrees(0.3), 17.18873385392469626303, "GetDegrees 1") 37 | Assert.Near(Math.GetDegrees(-2), -114.5915590261646417535, "GetDegrees 2") 38 | 39 | ' GetRadians 40 | Assert.Near(Math.GetRadians(17.18873385392469626303), 0.3, "GetRadians 1") 41 | Assert.Near(Math.GetRadians(-114.5915590261646417535), -2, "GetRadians 2") 42 | 43 | ' Log 44 | Assert.Equal(Math.Log(100), 2, "Log 1") 45 | Assert.Near(Math.Log(23), 1.36172783601759287886, "Log 2") 46 | Assert.Near(Math.Log(0.00021), -3.677780705266080, "Log 3") 47 | 48 | ' Max 49 | Assert.Equal(Math.Max(3,7), 7, "Max 1") 50 | Assert.Equal(Math.Max(-3,7), 7, "Max 2") 51 | Assert.Equal(Math.Max(-3,-7), -3, "Max 3") 52 | Assert.Equal(Math.Max(0,0), 0, "Max 4") 53 | 54 | ' Min 55 | Assert.Equal(Math.Min(3,7), 3, "Min 1") 56 | Assert.Equal(Math.Min(-3,7), -3, "Min 2") 57 | Assert.Equal(Math.Min(-3,-7), -7, "Min 3") 58 | Assert.Equal(Math.Min(0,0), 0, "Min 4") 59 | 60 | ' NaturalLog 61 | Assert.Near(Math.NaturalLog(100), 4.605170185988091368, "NaturalLog 1") 62 | Assert.Near(Math.NaturalLog(23), 3.135494215929149690, "NaturalLog 2") 63 | Assert.Near(Math.NaturalLog(0.00021), -8.46840302724680542, "NaturalLog 3") 64 | 65 | ' PI 66 | Assert.Near(Math.PI, 3.141592653589793238, "PI") 67 | 68 | ' Power 69 | Assert.Near(Math.Power(14,2), 196, "Power 1") 70 | Assert.Near(Math.Power(1.5,2.4), 2.6461778006805155, "Power 2") 71 | Assert.Near(Math.Power(13,0.1), 1.2923922207808318, "Power 3") 72 | 73 | ' Remainder 74 | Assert.Near(Math.Remainder(17,3), 2, "Remainder 1") 75 | Assert.Near(Math.Remainder(53.7,3.2), 2.5, "Remainder 2") 76 | Assert.Near(Math.Remainder(-53.7,3.2), -2.5, "Remainder 3") 77 | Assert.Near(Math.Remainder(53.7,-3.2), 2.5, "Remainder 4") 78 | Assert.Near(Math.Remainder(-53.7,-3.2), -2.5, "Remainder 5") 79 | 80 | ' Round 81 | Assert.Equal(Math.Round(234332.2), 234332, "Round 1") 82 | Assert.Equal(Math.Round(4.1), 4, "Round 2") 83 | Assert.Equal(Math.Round(4.8), 5, "Round 3") 84 | 'Assert.Equal(Math.Round(4.5), 4, "Round 4") ' round at 0.5 to reach even 85 | Assert.Equal(Math.Round(5.5), 6, "Round 5") ' round at 0.5 to reach even 86 | Assert.Equal(Math.Round(-0.8), -1, "Round 6") 87 | Assert.Equal(Math.Round(-1.5), -2, "Round 7") ' round at 0.5 to reach even 88 | 'Assert.Equal(Math.Round(-2.5), -2, "Round 8") ' round at 0.5 to reach even 89 | 90 | ' Sin 91 | Assert.Near(Math.Sin(0.5), 0.4794255386042030, "Sin 1") 92 | Assert.Near(Math.Sin(2.5), 0.5984721441039564, "Sin 2") 93 | 94 | ' SquareRoot 95 | Assert.Near(Math.SquareRoot(2), 1.414213562373095, "SquareRoot 1") 96 | Assert.Near(Math.SquareRoot(17), 4.123105625617660, "SquareRoot 2") 97 | Assert.Equal(Math.SquareRoot(16), 4, "SquareRoot 3") 98 | Assert.Equal(Math.SquareRoot(0), 0, "SquareRoot 4") 99 | 100 | ' Tan 101 | Assert.Near(Math.Tan(0.0010), 0.001000000333333, "Tan 1") 102 | Assert.Near(Math.Tan(3), -0.1425465430742778, "Tan 2") 103 | Assert.Near(Math.Tan(-3), 0.1425465430742778, "Tan 3") 104 | 105 | ' Basic operations 106 | A = 15 107 | B = 1 108 | C = 3 109 | Z = 0 110 | Assert.Equal(A/3, 5, "Division 1") 111 | Assert.Equal(-A/3, -5, "Division 2") 112 | Assert.Equal(A/-3, -5, "Division 3") 113 | Assert.Equal(B/0, 0, "Division 4") 114 | Assert.Equal(B*1.5*2, 3.0, "Multiplication 1") 115 | Assert.Equal(B*1.5*-2, -3, "Multiplication 2") 116 | Assert.Equal(B*1.5*-0, 0, "Multiplication 3") 117 | Assert.Equal(-Z, Z, "Negative Zero") 118 | Assert.Equal(A-B-C, 11, "Subtract not left to right") 119 | Assert.Equal(A-B+C, 17, "Add/subtract not left to right") 120 | 121 | LCD.Clear() 122 | LCD.Text(1,50,50,1,"OK") 123 | Buttons.Wait() 124 | -------------------------------------------------------------------------------- /testsuite/languagefeatures/MultiThreading.sb: -------------------------------------------------------------------------------- 1 | a=1 2 | Thread.Run = changer 3 | 4 | While "true" 5 | x = a 6 | x = x+a 7 | If x<>2 And x<>4 then 8 | TextWindow.WriteLine("Found miss-match") 9 | endif 10 | endwhile 11 | 12 | 13 | Sub changer 14 | While "True" 15 | A = 1 16 | A = 1 17 | A = 1 18 | A = 1 19 | A = 1 20 | A = 2 21 | A = 2 22 | A = 2 23 | A = 2 24 | A = 2 25 | endwhile 26 | endsub 27 | -------------------------------------------------------------------------------- /testsuite/languagefeatures/NestedExpressions.sb: -------------------------------------------------------------------------------- 1 | LCD.Clear() 2 | 3 | A = 5 4 | B = Math.Abs(-4) 5 | C = (17-5)*(A-3)+B/2 6 | D = (A*B)*(A+B)-((6*C)+(6*4*7*Math.Abs(-4)*3*A/12))*(4*B)-444 7 | 8 | LCD.Text(1,0,0, 1, "A: "+(A-0)) 9 | LCD.Text(1,0,16, 1, "B: "+(B+B)) 10 | LCD.Text(1,0,32, 1, "C: "+C*3) 11 | LCD.Text(1,0,48, 1, "D: "+(D+0)) 12 | 13 | If ((A+B)>(C+D)) THEN 14 | LCD.Text(1,0,64, 1, "(A+B)>(C+D)") 15 | EndIf 16 | If (A>(C+D)) THEN 17 | LCD.Text(1,0,80, 1, "A>(C+D)") 18 | EndIf 19 | 20 | Program.Delay(1000000) -------------------------------------------------------------------------------- /testsuite/languagefeatures/OperatorPrecedence.sb: -------------------------------------------------------------------------------- 1 | 2 | Assert.Equal(4+1*5, 9, "mul before plus") 3 | Assert.Equal(4-1*5, -1, "mul before minus") 4 | Assert.Equal(10/5+7, 9, "div before plus") 5 | Assert.Equal(4-10/5, 2, "div before minus") 6 | 7 | Assert.Equal(4*5*6/3, 40, "left to right 1") 8 | Assert.Equal(4/2*6, 12, "left to right 2") 9 | Assert.Equal(4/2/2, 1, "left to right 3") 10 | Assert.Equal(4-3+5, 6, "left to right 4") 11 | 12 | If "True" or "False" and "False" Then 13 | ' OK 14 | Else 15 | Assert.Failed("OR must be weaker than AND") 16 | EndIf 17 | 18 | If "False" and "True" or "False" and "True" Then 19 | Assert.Failed("OR is evaluated after AND") 20 | EndIf 21 | 22 | If "False" And "True" <> "True" then 23 | Assert.Failed("Comparator must be evaluated before AND") 24 | EndIf 25 | 26 | 27 | LCD.Clear() 28 | LCD.Text(1, 50,50, 1, "OK") 29 | Buttons.Wait() 30 | -------------------------------------------------------------------------------- /testsuite/languagefeatures/ProgramConstructs.sb: -------------------------------------------------------------------------------- 1 | LCD.Clear() 2 | 3 | y=0 4 | a=-2 5 | tests() 6 | 7 | y=16 8 | a=6 9 | tests() 10 | 11 | y=32 12 | a=15 13 | tests() 14 | 15 | y=48 16 | a=25 17 | tests() 18 | 19 | y=64 20 | a=99 21 | tests() 22 | 23 | 24 | For i=0 to 9 25 | LCD.Text(1, i*15, 80, 1, i) 26 | EndFor 27 | For i=10 to 3 step -2 28 | LCD.Text(1, i*12, 96, 1, i) 29 | EndFor 30 | 31 | j=15 32 | While j<25 33 | LCD.Text(1, j*16 - (15*16), 112, 1, j) 34 | j = j+1 35 | endwhile 36 | 37 | 38 | 39 | 40 | 41 | Sub tests 42 | 43 | LCD.Text(1, 0,y, 1, a) 44 | 45 | If a<4 Then 46 | LCD.Text(1, 25,y, 1, "a<4") 47 | ElseIf a<10 then 48 | LCD.Text(1, 25,y, 1, "a<10") 49 | ElseIf a>20 then 50 | LCD.Text(1, 25,y, 1, "a>20") 51 | Else 52 | LCD.Text(1, 25,y, 1, "a=?") 53 | EndIf 54 | 55 | If a<=-1 Then 56 | LCD.Text(1, 65,y, 1, "a<=-1") 57 | ElseIf a>=50 then 58 | LCD.Text(1, 65,y, 1, "a>=50") 59 | ElseIf a=6 then 60 | LCD.Text(1, 65,y, 1, "a=6") 61 | ElseIf a<>25 then 62 | LCD.Text(1, 65,y, 1, "a<>25") 63 | Else 64 | LCD.Text(1, 65,y, 1, "a=?") 65 | EndIf 66 | 67 | EndSub 68 | 69 | 70 | Program.Delay(1000000) 71 | 72 | 73 | -------------------------------------------------------------------------------- /testsuite/languagefeatures/RecursionTest.sb: -------------------------------------------------------------------------------- 1 | LCD.Clear() 2 | 3 | y = 0 4 | c = 0 5 | print() 6 | LCD.Text(1,70,30,1,"Done") 7 | Program.Delay(10000) 8 | 9 | sub print 10 | LCD.Text(1,0,y,1,Text.GetSubText(" ",1,c)+">"+c) 11 | y=y+12 12 | If c<4 Then 13 | c = c+1 14 | print() 15 | c = c-1 16 | endif 17 | LCD.Text(1,0,y,1,Text.GetSubText(" ",1,c)+"<"+c) 18 | y=y+12 19 | endsub 20 | 21 | -------------------------------------------------------------------------------- /testsuite/languagefeatures/SpaghettiCode.sb: -------------------------------------------------------------------------------- 1 | LCD.Clear() 2 | X=0 3 | Y=0 4 | 5 | Goto hello 6 | 7 | l1: 8 | if (y<60) then 9 | Goto l2 10 | Else 11 | Goto programend 12 | EndIf 13 | 14 | hello: 15 | LCD.Text(1,0,y,1,"HELLO") 16 | y = y+ 16 17 | Goto l1 18 | 19 | 20 | If (1=2) then 21 | l2: 22 | LCD.Text(1,0,y,1,"WORLD") 23 | y = y+ 16 24 | Goto hello 25 | EndIf 26 | 27 | Sub MYSUB 28 | l5 : 29 | LCD.Text(1,0,y,1,"LABEL IN SUB") 30 | y=y+16 31 | ' Goto totalover 32 | Program.Delay(1000) 33 | endsub 34 | 35 | programend : 36 | LCD.Text(1,0,y,1,".. END") 37 | y = y + 16 38 | 39 | MYSUB() 40 | 41 | totalover: 42 | Program.Delay(10000000) 43 | 44 | 45 | -------------------------------------------------------------------------------- /testsuite/languagefeatures/TextTest.sb: -------------------------------------------------------------------------------- 1 | a = "long string an such" 2 | b = "short" 3 | c = "else" 4 | d = "TRUE" 5 | e = "tRUe" 6 | upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ <6/31#+512" 7 | lower = "abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ <6/31#+512" 8 | 9 | ' Append 10 | Assert.Equal("text","text", "Assert itself is buggy") 11 | Assert.Equal(Text.Append("foo","bar"), "foobar", "Normal Append") 12 | Assert.Equal(Text.Append("","bar"), "bar", "Append with empty left side") 13 | Assert.Equal(Text.Append("foo""n",""), "foo""n", "Append with empty right side") 14 | Assert.Equal(Text.Append("",""), "", "Append with empty arguments") 15 | 16 | ' ConvertToLowerCase 17 | Assert.Equal(Text.ConvertToLowerCase("Nixi"),"nixi", "Normal ConvertToLowerCase") 18 | Assert.Equal(Text.ConvertToLowerCase(""),"", "ConvertToLowerCase without parameter") 19 | Assert.Equal(Text.ConvertToLowerCase("ÄöüÜÖ"),"äöüüö", "ConvertToLowerCase with 'Umlaute'") 20 | Assert.Equal(Text.ConvertToLowerCase(upper),lower, "ConvertToLowerCase with full latin-1 range") 21 | 22 | ' ConvertToUpperCase 23 | Assert.Equal(Text.ConvertToUpperCase("Nixi"),"NIXI", "Normal ConvertToUpperCase") 24 | Assert.Equal(Text.ConvertToUpperCase(""),"", "ConvertToUpperCase without parameter") 25 | Assert.Equal(Text.ConvertToUpperCase("ÄöüÜÖ"),"ÄÖÜÜÖ", "ConvertToUpperCase with 'Umlaute'") 26 | Assert.Equal(Text.ConvertToUpperCase(lower),upper, "ConvertToUpperCase with full latin-1 range") 27 | 28 | ' EndsWith 29 | if Text.EndsWith("mini", "ni") then 30 | Else 31 | Assert.Failed("Normal EndsWith") 32 | EndIf 33 | if Text.EndsWith("mini", "Ni") then 34 | Assert.Failed("EndsWith must be case-sensitive") 35 | EndIf 36 | If Text.EndsWith("some", "") then 37 | Assert.Failed("EndsWith must not be True with empty string") 38 | endif 39 | If Text.EndsWith("", "") then 40 | Assert.Failed("EndsWith must not be True with empty string even if first argument is empty") 41 | endif 42 | 43 | ' GetCharacter 44 | Assert.Equal(Text.GetCharacter(65), "A", "Normal GetCharacter") 45 | Assert.Equal(Text.GetCharacter(65.7), "A", "GetCharacter with fractional code") 46 | Assert.Equal(Text.GetCharacter(48.0), "0", "GetCharacter with 0 fractional code") 47 | ' values outside range (<0 or >65535 deliver nonsense in Smallbasic) 48 | 49 | ' GetCharacterCode 50 | Assert.Equal(Text.GetCharacterCode("A"), 65, "Normal GetCharacterCode") 51 | Assert.Equal(Text.GetCharacterCode("Ä"), 196, "GetCharacterCode of Umlaut") 52 | Assert.Equal(Text.GetCharacterCode(""), 0, "GetCharacterCode of empty string") 53 | Assert.Equal(Text.GetCharacterCode("andmore"), 97, "GetCharacterCode of multi-letter string") 54 | 55 | ' GetIndexOf 56 | Assert.Equal(Text.GetIndexOf(a,"trin"),7,"normal GetIndexOf") 57 | Assert.Equal(Text.GetIndexOf("mini","mini and more"),0,"GetIndexOf with longer second parameter") 58 | Assert.Equal(Text.GetIndexOf("mini","IN"),0,"GetIndexOf must check case-sensitive") 59 | Assert.Equal(Text.GetIndexOf("TrUe","tRue"),0,"GetIndexOf must check case-sensitive for TRUE also") 60 | 61 | ' GetLength 62 | Assert.Equal(Text.GetLength("some"),4,"normal GetLength") 63 | Assert.Equal(Text.GetLength(""),0,"GetLength of empty string") 64 | 65 | ' GetSubText 66 | Assert.Equal(Text.GetSubText(a,4,4), "g st", "normal GetSubText") 67 | Assert.Equal(Text.GetSubText(b,3,15), "ort", "GetSubText exceeding length") 68 | Assert.Equal(Text.GetSubText(b,17,1), "", "GetSubText with start > length") 69 | Assert.Equal(Text.GetSubText(b,4,0), "", "GetSubText with zero length") 70 | Assert.Equal(Text.GetSubText(b,5,0.2), "t", "GetSubText with fractional length < 0.2") 71 | Assert.Equal(Text.GetSubText(b,5,0.8), "t", "GetSubText with fractional length < 0.8") 72 | Assert.Equal(Text.GetSubText(b,2,2.2), "ho", "GetSubText with large fractional length") 73 | Assert.Equal(Text.GetSubText(b,0,3), "", "GetSubText with start < 1") 74 | Assert.Equal(Text.GetSubText(b,-1.5,3), "", "GetSubText with start < 0") 75 | Assert.Equal(Text.GetSubText(b,0.5,3), "", "GetSubText with start < 1.0") 76 | Assert.Equal(Text.GetSubText(b,1.3,3), "sho", "GetSubText with fractional start") 77 | Assert.Equal(Text.GetSubText(b,1.7,3), "sho", "GetSubText with fractional start") 78 | Assert.Equal(Text.GetSubText(b,1.7,2.9), "sh", "GetSubText with fractional length") 79 | 80 | ' GetSubTextToEnd 81 | Assert.Equal(Text.GetSubTextToEnd(a,7), "tring an such", "normal SubTextToEnd") 82 | Assert.Equal(Text.GetSubTextToEnd(a,0), "", "SubTextToEnd with start = 0") 83 | Assert.Equal(Text.GetSubTextToEnd(a,0.5), "", "SubTextToEnd with start = 0.5") 84 | Assert.Equal(Text.GetSubTextToEnd(a,1.8), a, "SubTextToEnd with start = 1.8") 85 | Assert.Equal(Text.GetSubTextToEnd(a,2.1), "ong string an such", "SubTextToEnd with start = 2.1") 86 | Assert.Equal(Text.GetSubTextToEnd(a,20), "", "SubTextToEnd with start > length") 87 | 88 | ' IsSubText 89 | Assert.Equal(Text.IsSubText(a, "ong"), "True", "normal IsSubText") 90 | Assert.Equal(Text.IsSubText("", "ong"), "False", "IsSubText with empty first parameter") 91 | Assert.Equal(Text.IsSubText(a, ""), "False", "IsSubText with empty second parameter") 92 | 93 | ' StartsWith 94 | Assert.Equal(Text.StartsWith("mini","mi"), "True", "normal StartsWith") 95 | Assert.Equal(Text.StartsWith("mini","MI"), "False", "StartsWith must be case-sensitive") 96 | Assert.Equal(Text.StartsWith("mini",""), "False", "StartsWith with empty second parameter") 97 | Assert.Equal(Text.StartsWith("",""), "False", "StartsWith with empty parameters") 98 | 99 | ' Comparision with TRUE, true, and other 100 | If d=e then 101 | ' ok 102 | Else 103 | Assert.Failed(d+" and "+e+" must be equal") 104 | EndIf 105 | If "nixi"="NIXI" Then 106 | Assert.Failed("different casings must not be equal") 107 | EndIf 108 | 109 | 110 | LCD.Clear() 111 | LCD.Text(1,50,50,1,"OK") 112 | Buttons.Wait() 113 | 114 | -------------------------------------------------------------------------------- /testsuite/subcallalias.lms: -------------------------------------------------------------------------------- 1 | 2 | vmthread MAIN 3 | { 4 | loop: 5 | CALL SETLEDB 2 6 | 7 | DATA32 timer2 8 | TIMER_WAIT 500 timer2 9 | TIMER_READY timer2 10 | 11 | CALL SETLEDC 3 12 | 13 | DATA32 timer3 14 | TIMER_WAIT 500 timer3 15 | TIMER_READY timer3 16 | 17 | CALL SETLEDA 1 18 | 19 | DATA32 timer1 20 | TIMER_WAIT 500 timer1 21 | TIMER_READY timer1 22 | 23 | JR loop 24 | } 25 | 26 | subcall SETLEDA 27 | subcall SETLEDB 28 | subcall SETLEDC 29 | { 30 | IN_8 value 31 | UI_WRITE LED value 32 | } 33 | -------------------------------------------------------------------------------- /testsuite/threads.lms: -------------------------------------------------------------------------------- 1 | 2 | vmthread MAIN 3 | DATAS txt 20 4 | DATA16 y 5 | 6 | UI_DRAW CLEAN 7 | 8 | OBJECT_START BLINKER 9 | 10 | INIT_BYTES txt 10 65 66 67 68 69 32 48 49 50 0 11 | MOVE16_16 0 y 12 | 13 | loop: 14 | UI_DRAW SELECT_FONT 1 15 | UI_DRAW TEXT 1 10 y txt 16 | UI_DRAW UPDATE 17 | 18 | DATA32 timer 19 | TIMER_WAIT 400 timer 20 | TIMER_READY timer 21 | 22 | ADD16 y 10 y 23 | JR_LT16 y 128 loop 24 | 25 | PROGRAM_STOP -1 26 | } 27 | 28 | vmthread BLINKER 29 | { 30 | loop: 31 | UI_WRITE LED 3 32 | 33 | DATA32 timer1 34 | TIMER_WAIT 500 timer1 35 | TIMER_READY timer1 36 | 37 | UI_WRITE LED 0 38 | 39 | DATA32 timer2 40 | TIMER_WAIT 500 timer2 41 | TIMER_READY timer2 42 | 43 | JR loop 44 | } -------------------------------------------------------------------------------- /testsuite/variableparameter.lms: -------------------------------------------------------------------------------- 1 | 2 | vmthread MAIN 3 | DATAS txt 20 4 | 5 | INIT_BYTES txt 10 65 66 67 68 69 32 48 49 50 0 6 | 7 | UI_DRAW CLEAN 8 | UI_DRAW SELECT_FONT 1 9 | UI_DRAW TEXT 1 10 50 txt 10 | UI_DRAW UPDATE 11 | 12 | DATA32 timer 13 | TIMER_WAIT 5000 timer 14 | TIMER_READY timer 15 | } 16 | --------------------------------------------------------------------------------