master
xieguigang 5 years ago
parent 2d5597e1f5
commit 39e8751712

@ -1,6 +1,17 @@
Namespace Interpreter.Expressions
Imports LINQ.Runtime
Public Class ArrayExpression
Namespace Interpreter.Expressions
Public Class ArrayExpression : Inherits Expression
Dim seq As Expression()
Sub New(seq As IEnumerable(Of Expression))
Me.seq = seq.ToArray
End Sub
Public Overrides Function Exec(env As Environment) As Object
Throw New NotImplementedException()
End Function
End Class
End Namespace

@ -13,8 +13,10 @@ Namespace Interpreter.Query
Dim symbol As SymbolDeclare
Dim executeQueue As Expression()
Sub New(exec As IEnumerable(Of Expression))
executeQueue = exec.ToArray
Sub New(symbol As SymbolDeclare, sequence As Expression, exec As IEnumerable(Of Expression))
Me.executeQueue = exec.ToArray
Me.symbol = symbol
Me.sequence = sequence
End Sub
Public Overrides Function Exec(env As Environment) As Object

@ -7,5 +7,14 @@ Namespace Language
Sub New(name As Tokens, Optional text As String = Nothing)
Call MyBase.New(name, text)
End Sub
Public Overloads Shared Operator =(t As Token, c As (name As Tokens, text As String)) As Boolean
Return t.name = c.name AndAlso t.text = c.text
End Operator
Public Overloads Shared Operator <>(t As Token, c As (name As Tokens, text As String)) As Boolean
Return Not t = c
End Operator
End Class
End Namespace

@ -5,16 +5,22 @@ Imports Microsoft.VisualBasic.Language
Module StackParser
<Extension>
Private Function isKeywordFrom(t As Token) As Boolean
Friend Function isKeywordFrom(t As Token) As Boolean
Return isKeyword(t, "from")
End Function
Private Function isKeyword(t As Token, text As String) As Boolean
<Extension>
Friend Function isKeywordAggregate(t As Token) As Boolean
Return isKeyword(t, "aggregate")
End Function
<Extension>
Friend Function isKeyword(t As Token, text As String) As Boolean
Return t.name = Tokens.keyword AndAlso t.text.TextEquals(text)
End Function
<Extension>
Private Function isKeywordSelect(t As Token) As Boolean
Friend Function isKeywordSelect(t As Token) As Boolean
Return isKeyword(t, "select")
End Function
@ -30,7 +36,20 @@ Module StackParser
<Extension>
Public Iterator Function SplitByTopLevelStack(tokenList As IEnumerable(Of Token)) As IEnumerable(Of Token())
For Each block In tokenList.DoSplitByTopLevelStack
For Each block In tokenList.DoSplitByTopLevelStack(Function(t)
Return t.name = Tokens.keyword AndAlso Not t.text.TextEquals("as")
End Function)
If Not block.All(Function(t) t.name = Tokens.Terminator) Then
Yield block
End If
Next
End Function
<Extension>
Public Iterator Function SplitParameters(tokenList As IEnumerable(Of Token)) As IEnumerable(Of Token())
For Each block In tokenList.DoSplitByTopLevelStack(Function(t)
Return t.name = Tokens.Comma
End Function)
If Not block.All(Function(t) t.name = Tokens.Terminator) Then
Yield block
End If
@ -43,12 +62,12 @@ Module StackParser
''' <param name="tokenList"></param>
''' <returns></returns>
<Extension>
Private Iterator Function DoSplitByTopLevelStack(tokenList As IEnumerable(Of Token)) As IEnumerable(Of Token())
Private Iterator Function DoSplitByTopLevelStack(tokenList As IEnumerable(Of Token), delimiter As Func(Of Token, Boolean)) As IEnumerable(Of Token())
Dim block As New List(Of Token)
Dim stack As New Stack(Of String)
For Each item As Token In tokenList.Where(Function(t) t.name <> Tokens.Terminator AndAlso t.name <> Tokens.Comment)
If item.name = Tokens.keyword AndAlso Not item.text.TextEquals("as") Then
If delimiter(item) Then
If stack.Count > 0 Then
block.Add(item)
Else

@ -1,5 +1,6 @@
Imports System.Runtime.CompilerServices
Imports LINQ.Interpreter.Expressions
Imports LINQ.Interpreter.Query
Imports LINQ.Language
Namespace Script
@ -10,11 +11,86 @@ Namespace Script
Public Function PopulateQueryExpression(tokens As IEnumerable(Of Token)) As Expression
Dim blocks = tokens.SplitByTopLevelStack.ToArray
If blocks(Scan0).First.isKeywordFrom Then
Return blocks(Scan0).CreateProjectionQuery(blocks.Skip(1).ToArray)
ElseIf blocks(Scan0).First.isKeywordAggregate Then
Return blocks(Scan0).CreateAggregateQuery(blocks.Skip(1).ToArray)
Else
Throw New SyntaxErrorException
End If
End Function
<Extension>
Private Function CreateProjectionQuery(symbol As Token(), blocks As Token()()) As ProjectionExpression
Dim symbolExpr As SymbolDeclare = symbol.ParseExpression
Dim i As Integer = 0
Dim seq As Expression = blocks.GetSequence(offset:=i)
Dim exec As Expression() = blocks.Skip(i).PopulateExpressions.ToArray
Dim proj As New ProjectionExpression(symbolExpr, seq, exec)
Return proj
End Function
<Extension>
Private Iterator Function PopulateExpressions(blocks As IEnumerable(Of Token())) As IEnumerable(Of Expression)
For Each blockLine As Token() In blocks
Yield ParseExpression(blockLine)
Next
End Function
<Extension>
Private Function GetSequence(blocks As Token()(), ByRef offset As Integer) As Expression
If Not blocks(Scan0).First.isKeyword("in") Then
Throw New SyntaxErrorException
ElseIf blocks(Scan0).Length = 1 Then
offset = 2
Return blocks(1).ParseExpression
Else
offset = 1
Return blocks(0).ParseExpression
End If
End Function
<Extension>
Private Function CreateAggregateQuery(symbol As Token(), blocks As Token()()) As AggregateExpression
Dim symbolExpr As SymbolDeclare = symbol.ParseExpression
Dim seq As Expression
End Function
Public Function ParseExpression(tokens As IEnumerable(Of Token)) As Expression
<Extension>
Public Function ParseExpression(tokenList As Token()) As Expression
If tokenList(Scan0).isKeywordFrom OrElse tokenList(Scan0).isKeywordAggregate OrElse tokenList(Scan0).isKeyword("let") Then
' declare new symbol
Dim name As String = tokenList(1).text
Dim type As String = "any"
If tokenList.Length > 2 Then
type = tokenList(3).text
End If
Return New SymbolDeclare With {.symbolName = name, .type = type}
End If
Dim blocks = tokenList.SplitByTopLevelStack.ToArray
If blocks.Length = 1 Then
tokenList = blocks(Scan0)
If tokenList.First = (Tokens.Open, "[") OrElse tokenList.First = (Tokens.Open, "{") Then
Return tokenList.Skip(1).Take(tokenList.Length - 2).GetVector
End If
End If
Throw New NotImplementedException
End Function
<Extension>
Private Function GetVector(tokenList As IEnumerable(Of Token)) As Expression
Dim blocks = tokenList.SplitParameters.Select(Function(b) If(b.Length = 1, b, b.Skip(1).ToArray)).ToArray
Dim elements As Expression() = blocks.Select(AddressOf ParseExpression).ToArray
Dim vec As New ArrayExpression(elements)
Return vec
End Function
End Module
End Namespace
Loading…
Cancel
Save