diff --git a/R/R.sln b/R.sln similarity index 96% rename from R/R.sln rename to R.sln index ffc6ec51a..2281d1021 100644 --- a/R/R.sln +++ b/R.sln @@ -1,11 +1,11 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26430.12 +VisualStudioVersion = 15.0.26228.9 MinimumVisualStudioVersion = 10.0.40219.1 Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "R", "R\R.vbproj", "{0C2EB77C-39F2-460D-A3F8-CE905F867637}" EndProject -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "+Microsoft.VisualBasic.Architecture.Framework", "..\..\..\Source\Repos\sciBASIC\Microsoft.VisualBasic.Architecture.Framework\+Microsoft.VisualBasic.Architecture.Framework.vbproj", "{FECCE1FD-E1D4-49E3-A668-60BB5E7AED99}" +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "+Microsoft.VisualBasic.Architecture.Framework", "..\runtime\sciBASIC#\Microsoft.VisualBasic.Architecture.Framework\+Microsoft.VisualBasic.Architecture.Framework.vbproj", "{FECCE1FD-E1D4-49E3-A668-60BB5E7AED99}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/R/R/App.config b/R/App.config similarity index 100% rename from R/R/App.config rename to R/App.config diff --git a/R/Interpreter/SyntaxParser.vb b/R/Interpreter/SyntaxParser.vb new file mode 100644 index 000000000..ba139089b --- /dev/null +++ b/R/Interpreter/SyntaxParser.vb @@ -0,0 +1,65 @@ +Imports System.Runtime.CompilerServices +Imports Microsoft.VisualBasic.Scripting.TokenIcer + +Public Module SyntaxParser + + Const SyntaxNotSupport$ = "The syntax is currently not support yet!" + + ''' + ''' Convert the string token model as the language runtime model + ''' + ''' + ''' + Public Function Parse(statement As Statement(Of LanguageTokens)) As PrimitiveExpression + Dim expression As PrimitiveExpression = Nothing + + If TryParseObjectDeclare(statement, expression) Then + Return expression + ElseIf TryParseTypedObjectDeclare(statement, expression) Then + Return expression + End If + + Dim source As New Exception(statement.GetXml) + Throw New SyntaxErrorException(SyntaxNotSupport, source) + End Function + + ''' + ''' ```R + ''' var x <- "string"; + ''' ``` + ''' + ''' + ''' + Public Function TryParseObjectDeclare(statement As Statement(Of LanguageTokens), ByRef out As PrimitiveExpression) As Boolean + Dim tokens = statement.tokens + + If Not tokens.First.name = LanguageTokens.var Then + Return False + ElseIf Not tokens(2).name = LanguageTokens.LeftAssign Then + Return False + End If + + Dim var$ = tokens(1).Text + + End Function + + ''' + ''' ```R + ''' var x as string <- "string"; + ''' ``` + ''' + ''' + ''' + Public Function TryParseTypedObjectDeclare(statement As Statement(Of LanguageTokens), ByRef out As PrimitiveExpression) As Boolean + Dim tokens = statement.tokens + + If Not tokens.First.name = LanguageTokens.var Then + Return False + ElseIf Not tokens(2).Text = "as" Then + Return False + End If + + Dim var$ = tokens(1).Text + + End Function +End Module diff --git a/R/R/TokenIcer.vb b/R/Interpreter/TokenIcer.vb similarity index 99% rename from R/R/TokenIcer.vb rename to R/Interpreter/TokenIcer.vb index ff2fedf27..b715ed038 100644 --- a/R/R/TokenIcer.vb +++ b/R/Interpreter/TokenIcer.vb @@ -3,7 +3,7 @@ Imports Microsoft.VisualBasic.Emit.Marshal Imports Microsoft.VisualBasic.Language Imports Microsoft.VisualBasic.Scripting.TokenIcer Imports Microsoft.VisualBasic.Text -Imports langToken = Microsoft.VisualBasic.Scripting.TokenIcer.Token(Of R.LanguageTokens) +Imports langToken = Microsoft.VisualBasic.Scripting.TokenIcer.Token(Of SMRUCC.Rsharp.LanguageTokens) Public Module TokenIcer diff --git a/R/R/LangModels.vb b/R/LanguageTokens.vb similarity index 100% rename from R/R/LangModels.vb rename to R/LanguageTokens.vb diff --git a/R/R/Module1.vb b/R/Module1.vb similarity index 100% rename from R/R/Module1.vb rename to R/Module1.vb diff --git a/R/R/My Project/Application.Designer.vb b/R/My Project/Application.Designer.vb similarity index 100% rename from R/R/My Project/Application.Designer.vb rename to R/My Project/Application.Designer.vb diff --git a/R/R/My Project/Application.myapp b/R/My Project/Application.myapp similarity index 100% rename from R/R/My Project/Application.myapp rename to R/My Project/Application.myapp diff --git a/R/R/My Project/AssemblyInfo.vb b/R/My Project/AssemblyInfo.vb similarity index 100% rename from R/R/My Project/AssemblyInfo.vb rename to R/My Project/AssemblyInfo.vb diff --git a/R/R/My Project/Resources.Designer.vb b/R/My Project/Resources.Designer.vb similarity index 81% rename from R/R/My Project/Resources.Designer.vb rename to R/My Project/Resources.Designer.vb index d5bc74cff..27f9badda 100644 --- a/R/R/My Project/Resources.Designer.vb +++ b/R/My Project/Resources.Designer.vb @@ -11,9 +11,10 @@ Option Strict On Option Explicit On +Imports System Namespace My.Resources - + 'This class was auto-generated by the StronglyTypedResourceBuilder 'class via a tool like ResGen or Visual Studio. 'To add or remove a member, edit your .ResX file then rerun ResGen @@ -21,40 +22,40 @@ Namespace My.Resources ''' ''' A strongly-typed resource class, for looking up localized strings, etc. ''' - _ + _ Friend Module Resources - + Private resourceMan As Global.System.Resources.ResourceManager - + Private resourceCulture As Global.System.Globalization.CultureInfo - + ''' ''' Returns the cached ResourceManager instance used by this class. ''' - _ + _ Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager Get If Object.ReferenceEquals(resourceMan, Nothing) Then - Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("R.Resources", GetType(Resources).Assembly) + Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("SMRUCC.Rsharp.Resources", GetType(Resources).Assembly) resourceMan = temp End If Return resourceMan End Get End Property - + ''' ''' Overrides the current thread's CurrentUICulture property for all ''' resource lookups using this strongly typed resource class. ''' - _ + _ Friend Property Culture() As Global.System.Globalization.CultureInfo Get Return resourceCulture End Get - Set(ByVal value As Global.System.Globalization.CultureInfo) + Set resourceCulture = value End Set End Property diff --git a/R/R/My Project/Resources.resx b/R/My Project/Resources.resx similarity index 100% rename from R/R/My Project/Resources.resx rename to R/My Project/Resources.resx diff --git a/R/R/My Project/Settings.Designer.vb b/R/My Project/Settings.Designer.vb similarity index 53% rename from R/R/My Project/Settings.Designer.vb rename to R/My Project/Settings.Designer.vb index 5d551f863..85e63c8f4 100644 --- a/R/R/My Project/Settings.Designer.vb +++ b/R/My Project/Settings.Designer.vb @@ -13,42 +13,42 @@ Option Explicit On Namespace My - - _ + + _ Partial Friend NotInheritable Class MySettings Inherits Global.System.Configuration.ApplicationSettingsBase - - Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings), MySettings) - + + Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings) + #Region "My.Settings Auto-Save Functionality" #If _MyType = "WindowsForms" Then - Private Shared addedHandler As Boolean + Private Shared addedHandler As Boolean - Private Shared addedHandlerLockObject As New Object + Private Shared addedHandlerLockObject As New Object - _ - Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs) - If My.Application.SaveMySettingsOnExit Then - My.Settings.Save() - End If - End Sub + _ + Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs) + If My.Application.SaveMySettingsOnExit Then + My.Settings.Save() + End If + End Sub #End If #End Region - + Public Shared ReadOnly Property [Default]() As MySettings Get - + #If _MyType = "WindowsForms" Then - If Not addedHandler Then - SyncLock addedHandlerLockObject - If Not addedHandler Then - AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings - addedHandler = True - End If - End SyncLock - End If + If Not addedHandler Then + SyncLock addedHandlerLockObject + If Not addedHandler Then + AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings + addedHandler = True + End If + End SyncLock + End If #End If Return defaultInstance End Get @@ -57,16 +57,16 @@ Namespace My End Namespace Namespace My - - _ + + _ Friend Module MySettingsProperty - - _ - Friend ReadOnly Property Settings() As Global.R.My.MySettings + + _ + Friend ReadOnly Property Settings() As Global.SMRUCC.Rsharp.My.MySettings Get - Return Global.R.My.MySettings.Default + Return Global.SMRUCC.Rsharp.My.MySettings.Default End Get End Property End Module diff --git a/R/R/My Project/Settings.settings b/R/My Project/Settings.settings similarity index 100% rename from R/R/My Project/Settings.settings rename to R/My Project/Settings.settings diff --git a/R/R#.ico b/R/R#.ico new file mode 100644 index 000000000..f164dadaa Binary files /dev/null and b/R/R#.ico differ diff --git a/R/R/R.vbproj b/R/R.vbproj similarity index 79% rename from R/R/R.vbproj rename to R/R.vbproj index cfe2b1ea0..c45edc030 100644 --- a/R/R/R.vbproj +++ b/R/R.vbproj @@ -6,8 +6,8 @@ AnyCPU {0C2EB77C-39F2-460D-A3F8-CE905F867637} Exe - R.Module1 - R + SMRUCC.Rsharp.Module1 + SMRUCC.Rsharp R 512 Console @@ -46,6 +46,9 @@ On + + R#.ico + @@ -68,9 +71,17 @@ + - - + + + + + + + + + True @@ -108,10 +119,17 @@ - - {fecce1fd-e1d4-49e3-a668-60bb5e7aed99} + + {FECCE1FD-E1D4-49E3-A668-60BB5E7AED99} +Microsoft.VisualBasic.Architecture.Framework + + + + + + + \ No newline at end of file diff --git a/R/runtime/BindVariable.vb b/R/runtime/BindVariable.vb new file mode 100644 index 000000000..edf42eb5e --- /dev/null +++ b/R/runtime/BindVariable.vb @@ -0,0 +1,56 @@ +Imports System.Reflection +Imports Microsoft.VisualBasic.Emit.Delegates + +''' +''' ``R#``脚本会通过这个变量对象将包之中的模块变量或者Class之中的共享变量作为一个R的内部变量 +''' +Public Class BindVariable : Inherits Variable + + ''' + ''' 编译之后所产生的变量值的设置或者获取的过程 + ''' + ReadOnly getValue As Func(Of Object), setValue As Action(Of Object) + + ''' + ''' 这个属性获取的是包之中的模块变量的值 + ''' + ''' + Public Overrides Property Value As Object + Get + Return getValue() + End Get + Set(value As Object) + Call setValue(value) + MyBase.Value = value + End Set + End Property + + ''' + ''' 这个变量对象在运行时环境之中的原来的位置 + ''' + ''' + Public ReadOnly Property Source As String + + Sub New(field As FieldInfo) + Call Me.New(src:=field) + + With field + getValue = StaticFieldGet(.DeclaringType, .Name) + setValue = StaticFieldSet(.DeclaringType, .Name) + End With + End Sub + + Private Sub New(src As MemberInfo) + Name = src.Name + Source = src.Source + End Sub + + Sub New([property] As PropertyInfo) + Call Me.New(src:=[property]) + + With [property] + getValue = StaticPropertyGet(.DeclaringType, .Name) + setValue = StaticPropertySet(.DeclaringType, .Name) + End With + End Sub +End Class diff --git a/R/runtime/Expression/FunctionExpression.vb b/R/runtime/Expression/FunctionExpression.vb new file mode 100644 index 000000000..19bf6a16c --- /dev/null +++ b/R/runtime/Expression/FunctionExpression.vb @@ -0,0 +1,3 @@ +Public Class FunctionExpression + +End Class diff --git a/R/runtime/Expression/LiteralExpression.vb b/R/runtime/Expression/LiteralExpression.vb new file mode 100644 index 000000000..4c7477d56 --- /dev/null +++ b/R/runtime/Expression/LiteralExpression.vb @@ -0,0 +1,11 @@ +Imports Microsoft.VisualBasic.Scripting.TokenIcer + +''' +''' 数字,字符串,逻辑值之类的值表达式,也可以称作为常数 +''' +Public Class LiteralExpression : Inherits PrimitiveExpression + + Sub New(token As Token(Of LanguageTokens)) + + End Sub +End Class diff --git a/R/runtime/Expression/OperatorExpression.vb b/R/runtime/Expression/OperatorExpression.vb new file mode 100644 index 000000000..53f81ae11 --- /dev/null +++ b/R/runtime/Expression/OperatorExpression.vb @@ -0,0 +1,6 @@ +''' +''' Logical and arithmetic expression +''' +Public Class OperatorExpression + +End Class diff --git a/R/runtime/Expression/PrimitiveExpression.vb b/R/runtime/Expression/PrimitiveExpression.vb new file mode 100644 index 000000000..5d380d83e --- /dev/null +++ b/R/runtime/Expression/PrimitiveExpression.vb @@ -0,0 +1,6 @@ +''' +''' The very base expression in the R# language +''' +Public Class PrimitiveExpression + +End Class diff --git a/R/runtime/TypeCodes.vb b/R/runtime/TypeCodes.vb new file mode 100644 index 000000000..fe37c14a6 --- /dev/null +++ b/R/runtime/TypeCodes.vb @@ -0,0 +1,37 @@ +''' +''' The R# types +''' +Public Enum TypeCodes + ''' + ''' vector + ''' + [integer] + ''' + ''' vector + ''' + [uinteger] + ''' + ''' numeric vector + ''' + [double] + ''' + ''' vector + ''' + [string] + ''' + ''' vector + ''' + [char] + ''' + ''' vector + ''' + [boolean] + ''' + ''' Class type in R# + ''' + [list] + ''' + ''' Object type in R# + ''' + [generic] +End Enum diff --git a/R/runtime/Variable.vb b/R/runtime/Variable.vb new file mode 100644 index 000000000..f7c9f63cd --- /dev/null +++ b/R/runtime/Variable.vb @@ -0,0 +1,31 @@ +Imports Microsoft.VisualBasic.ComponentModel.Collection.Generic +Imports Microsoft.VisualBasic.ComponentModel.DataSourceModel.Repository +Imports Microsoft.VisualBasic.Language +Imports Microsoft.VisualBasic.Scripting + +Public Class Variable + + Implements INamedValue + Implements Value(Of Object).IValueOf + + Public Property Name As String Implements IKeyedEntity(Of String).Key + Public Overridable Property Value As Object Implements Value(Of Object).IValueOf.value + + ''' + ''' Get the type of the current object . + ''' + ''' + Public Overloads ReadOnly Property [TypeOf] As Type + Get + If Value Is Nothing Then + Return GetType(Object) + Else + Return Value.GetType + End If + End Get + End Property + + Public Overrides Function ToString() As String + Return $"Dim {Name} As {Me.TypeOf.FullName} = {CStrSafe(Value)}" + End Function +End Class diff --git a/README.md b/README.md index 77bca3e0c..902065415 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,10 @@ +> [WARNING] This project is a work in progress and is not recommended for production use. + +![](./design/R-sharp.png) +> art work: http://www.clipartbest.com/clipart-di85MqodT + +The ``R#`` language its syntax is original derived from the ``R`` language, but with more modernized programming styles. The ``R#`` language its interpreter and .NET compiler is original writen in VisualBasic language, with native support for the .NET runtime. + ## R# language design ###### Code comments @@ -34,16 +41,18 @@ Dim m = { ###### Types -``R#`` language have sevral primitive type: +``R#`` language have several primitive type: -+ ``integer``, System.Int64 vector -+ ``double``, System.Double vector -+ ``uinteger``, System.UInt64 vector -+ ``string``, System.String vector -+ ``char``, System.Char vector -+ ``boolean``, System.Boolean vector +|primitive type in R|.NET type | +|-------------------|-------------------------| +|``integer`` |**System.Int64** vector | +|``double`` |**System.Double** vector | +|``uinteger`` |**System.UInt64** vector | +|``string`` |**System.String** vector | +|``char`` |**System.Char** vector | +|``boolean`` |**System.Boolean** vector| -And you can declare the user type by using ``list()`` function, example like: +Generally, the R language is not designed as an OOP language, and the R# language is not designed as an OOP lnaguge too. But you can still declare the user type by using ``list()`` function, example like: ```R var obj <- list(); @@ -51,23 +60,32 @@ var obj <- list(); # using with for object property initialize var obj <- list() with { $a <- 123; - $b <- "+++"; + $b <- "+++"; +} +``` + +Using ``with{}`` closure can makes the property initialize at the same time when you create your user type by using ``list()`` function. Just like what you does in VisualBasic: + +```vbnet +Dim obj As New With { + .a = 123, + .b = "+++" } ``` -generally, the parameter in a function is a generic type, so that a function definition like: +generally, the parameter in a function is generic type, so that a function its definition like: ```R test <- function(x) { } ``` -can accept any type you have input. but you can using the ``param as `` for limit the type as a specific type: +can accept any type you have input. but you can using the ``param as `` for constraint the type to a specific type(currently the user type that produced by ``list()`` function is not supported by this type constraint feature): ```R test.integer <- function(x as integer) { # the type constraint means the parameter only allow the integer vector type - # if the parameter is a string vector, then the interpreter will throw exceptions. + # if the parameter is a string vector, then the interpreter will throw exceptions. } ``` @@ -82,7 +100,7 @@ dataframe[, "name"] <- new.names; ###### String -Add new string contact and string interploate feature for ``R#``: +Add new string contact and string interploate feature for ``R#``, makes you more easier in the string manipulation: ```R var name <- first.name & " " & last.name; @@ -94,9 +112,11 @@ var his.name <- sprintf("%s %s", first.name, last.name); ###### Logical operators -+ and, andalso -+ or, orelse -+ not +The ``R#`` language using the VisualBasic logical operator system, as the ``&`` operator is conflicts with the string contact and ``|`` operator is conflicts with the pipeline operator. + ++ ``&&`` replaced by ``and``, ``andalso`` ++ ``||`` replaced by ``or``, ``orelse`` ++ ``!`` replaced by ``not`` ```R if (x <= 10 andalso y != 99) { @@ -113,7 +133,7 @@ Allows you bind operator on your custom type: ```R # binding operator only allows in the with closure in the object declare statement var me <- list() with { - %+% <- function($, other) { + %+% <- function($, other) { } %is% <- function($, other) { } @@ -160,9 +180,9 @@ End Function End Function Dim result = "hello world!" - .test1 - .test2(99) - .test3 + .test1 + .test2(99) + .test3 ``` All of the R function which have at least one parameter can be using in pipeline mode, using ``|`` as the pipeline operator: @@ -177,9 +197,9 @@ test3 <- function(a) { # Doing the exactly the same as VisualBasic pipeline in R language: var result <- "hello world!" - |test1 - |test2(99) - |test3; + |test1 + |test2(99) + |test3; # or you can just using the R function in normal way, and it is much complicated to read: var result <- test3(test2(test1("hello world"), 99)); ``` @@ -248,17 +268,33 @@ var [exitCode, stdout] <- @CLI; Tuple enable the R function returns multiple value at once: ```R +# this R function returns multiple value by using tuple: tuple.test <- function(a as integer, b as integer) { - return [a, b, a^b]; + return [a, b, a ^ b]; } +# and you can using tuple its member as the normal variable var [a, b, c] <- tuple.test(3, 2); if (a == 3) { - c = c + a + b; + c <- c + a + b; + # or using pipeline + c <- {a, b, c} | sum; } ``` +```vbnet +Dim tuple_test = Function(a As Integer, b As Integer) + Return (a, b, a ^ b) + End Function +Dim x As (a, b, c) = tuple_test(3, 2) + +If x.a = 3 Then + ' using pipeline + Dim c = {x.a, x.b, x.c}.Sum +End If +``` + ###### R object to tuple You can naturally convert the object as tuple value. The member in the tuple their name should matched the names in an object, so that you can doing something like this example in ``R#``: @@ -268,6 +304,8 @@ var obj <- list() with { $a <- 333; $b <- 999; } +# the tuple its member name should match the property name in you custom object type +# no order required in your tuple declaration: var [a, b] <- obj; ``` @@ -289,11 +327,14 @@ var d <- data.frame( b = {"a", "g", "y"}, t = {TRUE, TRUE, FALSE}); +# in a for loop, the tuple its member value is the cell value in dataframe for([a, b, c as "t"] in d) { println("%s = %s ? (%s)", a, b, c); } +# if directly convert the dataframe as tuple, +# then the tuple member is value is the column value in the dataframe var [a, b, booleans as "t"] <- d; ``` -If the tuple is applied on a for loop, then it means convert each row in dataframe as tuple, or just applied the tuple on the var declaring, then it means converts the columns in dataframe as the tuple, so that the variable in tuple is a vector with nrows of the dataframe. \ No newline at end of file +If the tuple is applied on a for loop, then it means convert each row in dataframe as tuple, or just applied the tuple on the var declaring, then it means converts the columns in dataframe as the tuple, so that the variable in tuple is a vector with nrows of the dataframe. diff --git a/Rsharp_compiler.MD b/Rsharp_compiler.MD new file mode 100644 index 000000000..fca2bb00e --- /dev/null +++ b/Rsharp_compiler.MD @@ -0,0 +1,45 @@ +By default, one ``R#`` script equivalent to a small program in sub **main**, like: + +example R script file: + +```R +# program.R + +var s as string <- "Hello world!"; +var expand <- function() { + s <- "{s} message from R#"; +} + +expand(); +println(s); +# Hello world! message from R# +``` + +equivalent to the VisualBasic program: + +```vbnet +' program.vb + +Module Program + + Sub Main() + + Dim s As String = "Hello world!" + Dim expand = Function() + s = $"{s} message from VisualBasic" + End Function + ' Hello world! message from VisualBasic + Call expand() + Call println(s) + End Sub +End Module +``` + +The you can using the ``R#`` compiler for compile you R script as a standard .NET program, using commandline: + +```bash +"/home/xieguigang/Rsharp/rc.exe" /compile --file "/home/xieguigang/test/program.R" --out "./hello.exe" + +./hello.exe +# Hello world! message from R# +``` diff --git a/design/R-sharp.png b/design/R-sharp.png new file mode 100644 index 000000000..d539341e6 Binary files /dev/null and b/design/R-sharp.png differ diff --git a/R/sourceTree.xml b/design/sourceTree.xml similarity index 100% rename from R/sourceTree.xml rename to design/sourceTree.xml diff --git a/R/syntax.r b/design/syntax.r similarity index 100% rename from R/syntax.r rename to design/syntax.r diff --git a/test/declare_variable.R b/test/declare_variable.R new file mode 100644 index 000000000..1c969c065 --- /dev/null +++ b/test/declare_variable.R @@ -0,0 +1,28 @@ +var x <- 123; # integer vector only have one element +var y <- {1, 2, 3}; # integer vector have 3 elements + +print(x); +# [1] 123 + +print(y); +# [1] 1 2 3 + +typeof(x); +# integer + +typeof(y); +# integer + +typeof(x) is typeof(y); +# [1] TRUE + +var t as double <- [100:1,-0.5]; +var i as integer <- [t="g2", n=666, s=FALSE]; +# type constraint error: object type can not be convert to an integer vector + +test.global <- function(x) { + return x + [x]; +} + +test.variable_not_found <- 123; +# object not found error: you must declare a variable using var statement before you use it! diff --git a/test/for_loop.R b/test/for_loop.R new file mode 100644 index 000000000..d2f314cc4 --- /dev/null +++ b/test/for_loop.R @@ -0,0 +1,40 @@ +var x <- {}; + +for(i in 1:100) { + x.append(i); +} + +var y <- {}; + +for(i in [80:100,0.25]) { + y.append(i); +} + +str(x); +# integer [1:100] 1 2 3 4 5 6 7 8 9 10 ... + +var g <- which x in y; + +str(g); +# integer [1:21] 80 81 82 83 84 85 86 87 88 89 ... + +g <- which not x in [10:100]; +# integer [1:9] 1 2 3 4 5 6 7 8 9 + +create.table <- function(min as integer, max as double) { + var x <- [min:max,0.1]; + var y <- x ^ 2; + var z <- -y; + + return data.frame(x, y, z); +} + +for([a as "x", b as "y", z] in create.table(1, 5)) { + print({a, b, z} | average); +} + +var [x1, y1, c1 as "z"] <- create.table(1, 5); + +str(x1); +str(y1); +str(c1); diff --git a/test/operator_binding.R b/test/operator_binding.R new file mode 100644 index 000000000..a67f4c241 --- /dev/null +++ b/test/operator_binding.R @@ -0,0 +1,38 @@ +imports "Microsoft.VisualBasic.dll"; + +var me <- list() with { + $name <- "xieguigang"; + $family <- {"xyz"}; + $display <- function() { + return $name & " has {$family:Length} families."; + } + + %+% <- function($, name as string) { + $family.append(name); + return $family; + } +} + +var out as string <- me + "abc"; + +str(out); +# string [1:2] "xyz" "abc" + +me$display(); +# xieguigang has 2 families. + +library("Microsoft.VisualBasic.Strings"); + +var index.string <- list() with { + $string <- "abcdefg"; + + %in% <- function(str, $) { + return InStr($string, str); + } +} + +"abcd" in index.string; +# [1] 1 + +"xyz" in index.string; +# [1] 0 diff --git a/test/tuple_test.R b/test/tuple_test.R new file mode 100644 index 000000000..0ba346b28 --- /dev/null +++ b/test/tuple_test.R @@ -0,0 +1,49 @@ +tuple.create <- function(a, b, c) { + return [a:ToString("F5"), b, c, {a, b, c} | sum]; +} + +var x <- tuple.create(1, 2, 3); + +x$X1; +# [1] 1.00000 + +x$X2; +# [1] 2 + +x$X3; +# [1] 3 + +x$X4:ToString("F2"); +# [1] 6.00 + +var [i, j, c, s] <- tuple.create(2, 3, 3); + +i; +# [1] 2.00000 + +j; +# [1] 3 + +c; +# [1] 3 + +str(s); +# numeric 8 + +var obj <- list() with { + $a <- 123; + $b <- "666"; +} + +str(obj); +# List of 2 +# $a: integer 123 +# $b: string "666" + +var [int, text] <- obj; + +str(int); +# integer 123 + +str(text); +# string "666"