Moved things around

This commit is contained in:
2022-10-22 05:58:19 +08:00
parent 49043117e2
commit ff8ba52a75
12 changed files with 297 additions and 123 deletions

View File

@@ -0,0 +1,32 @@
package parsers
import (
// "fmt"
engine "github.com/tgckpg/mmqlengine/mmql/engine"
stmtd "github.com/tgckpg/mmqlengine/mmql/statements"
)
/*
EXPECT: [Number] [Units]
OR
EXPECT: [FUNCTION]( ...params )
*/
func AmountStatement( lexer *engine.Lexer ) ( istmt stmtd.IStatement, err error ) {
stmt := stmtd.AmountStatement{}
val, err := lexer.ReadDecimal()
if err != nil {
return
}
stmt.SetValue( val )
unit, err := lexer.ReadAlpha()
if err != nil {
return
}
stmt.SetUnit( unit )
istmt = stmt
return
}

View File

@@ -0,0 +1,50 @@
package parsers
import (
// "fmt"
"strings"
"testing"
engine "github.com/tgckpg/mmqlengine/mmql/engine"
stmtd "github.com/tgckpg/mmqlengine/mmql/statements"
)
type _p struct {
amount float64
unit string
}
func TestAmountStatement( t *testing.T ) {
lexer := engine.Lexer{}
supportedStmts := map[string] func( *engine.Lexer ) ( stmtd.IStatement, error ) {
"AMOUNT": AmountStatement,
}
lexer.SupportedStmts = &supportedStmts
read_oks := map[string] _p {
"1 SHARES OF QQQ": _p{ 1, "SHARES" },
"1 QQQ": _p{ 1, "QQQ" },
"1 UNIT OF QQQ": _p{ 1, "UNIT" },
}
readAmount := engine.LexerExpect{
Statements: true,
Keywords: false,
Brackets: false,
Quotes: false,
Key: "AMOUNT",
}
for k := range read_oks {
lexer.SetReader( strings.NewReader( k ) )
stmt, err := lexer.ReadStatement( &readAmount )
if err != nil {
t.Error( err )
}
aStmt := any( stmt ).( stmtd.AmountStatement )
p, _ := read_oks[ k ]
if aStmt.Unit() != p.unit {
t.Errorf( "Expected \"%s\", got \"%s\" instead", p.unit, aStmt.Unit() )
}
}
}

View File

@@ -0,0 +1,96 @@
package parsers
import (
engine "github.com/tgckpg/mmqlengine/mmql/engine"
stmtd "github.com/tgckpg/mmqlengine/mmql/statements"
)
/*
EXPECT: BUY
THEN EXPECT: [AmountStatement] OF [FinancialInstrumentStatement]
THEN EXPECT: FOR [AmountStatement]
THEN EXPECT: FROM [ExchangeType]
THEN OPT EXPECT: [ExchangeType]
THEN OPT EXPECT: [AND|OR]
THEN EXPECT: [ActionExpression]
THEN OPT EXPECT: FOR EVERY
THEN EXPECT: [AmountType] OF [FinancialInstrumentType]
THEN EXPECT: [SOLD|BOUGHT] FROM [ExchangeType]
*/
func BuyStatement( lexer *engine.Lexer ) ( istmt stmtd.IStatement, err error ) {
orderStmt := stmtd.OrderStatement{}
orderStmt.Action = "BUY"
// AmountStatement
readAmount := engine.LexerExpect{
Statements: true,
Keywords: false,
Brackets: false,
Quotes: false,
Key: "AMOUNT",
}
_amountStmt, err := lexer.ReadStatement( &readAmount )
if err != nil {
return
}
amountStmt := any( _amountStmt ).( stmtd.AmountStatement )
orderStmt.SetAmount( &amountStmt )
var fiStmt stmtd.FinancialInstrumentStatement
// OF
err = lexer.ReadKeyword( "OF" )
if err != nil {
// try read FOR
err = lexer.ReadKeyword( "FOR" )
if err != nil {
return
}
// BUY 1 QQQ
fiStmt := stmtd.FinancialInstrumentStatement{}
fiStmt.Name = amountStmt.Unit()
// Equivalent to BUY 1 UNIT OF QQQ
amountStmt.SetUnit( "UNITS" )
} else {
// BUY 1 UNIT OF QQQ
readFI := engine.LexerExpect{
Statements: true,
Keywords: false,
Brackets: false,
Quotes: false,
Key: "FINANCIAL_INSTRUMENT",
}
_fiStmt, _err := lexer.ReadStatement( &readFI )
if _err != nil {
err = _err
return
}
fiStmt = any( _fiStmt ).( stmtd.FinancialInstrumentStatement )
// FOR
err = lexer.ReadKeyword( "FOR" )
if err != nil {
return
}
}
orderStmt.SetFinancialInstrument( &fiStmt )
// FOR [AmountStatement]
_forStmt, err := lexer.ReadStatement( &readAmount )
if err != nil {
return
}
forStmt := any( _forStmt ).( stmtd.AmountStatement )
orderStmt.SetFor( &forStmt )
istmt = orderStmt
return
}

View File

@@ -0,0 +1,57 @@
package parsers
import (
// "fmt"
"testing"
engine "github.com/tgckpg/mmqlengine/mmql/engine"
stmtd "github.com/tgckpg/mmqlengine/mmql/statements"
)
func TestBuyStatement( t *testing.T ) {
lexer := engine.Lexer{}
supportedStmts := map[string] func( *engine.Lexer ) ( stmtd.IStatement, error ) {
"BUY": BuyStatement,
"AMOUNT": AmountStatement,
"FINANCIAL_INSTRUMENT": FinancialInstrumentStatement,
}
lexer.SupportedStmts = &supportedStmts
var stmt stmtd.OrderStatement
_stmt, err := lexer.Parse( "BUY 1 SHARES OF QQQ FOR 10 USD FROM \"MyBrokerAccount\"" )
if err != nil {
t.Error( err )
} else {
stmt = any( _stmt ).( stmtd.OrderStatement )
if stmt.Amount().Unit() != "SHARES" {
t.Errorf( "Expected 1 SHARES Amount, got \"%s\" Amount", stmt.Amount().Unit() )
}
}
_stmt, err = lexer.Parse( "BUY 1 QQQ FOR MARKET_PRICE() FROM \"MyBrokerAccount\"" )
if err != nil {
t.Error( err )
} else {
stmt = any( _stmt ).( stmtd.OrderStatement )
if stmt.Amount().Unit() != "UNITS" {
t.Errorf( "Expected 1 UNITS Amount, got \"%s\" Amount", stmt.Amount().Unit() )
}
}
_, err = lexer.Parse( "BUY 1 QQQ FOR 10 USD FROM \"MyBrokerAccount\"" )
if err != nil {
t.Error( err )
}
_, err = lexer.Parse( `
BUY 1 SHARES OF BTC_ETF
FOR 10 USD
FROM "MyBrokerAccount"
WITH LIMIT OF PURCHASING_POWER( "MyBrokerAccount", "QQQ" )
FOR EVERY
1 BTC OF USD_BTC SOLD
FROM "CoinBase"
` )
if err != nil {
t.Error( err )
}
}

View File

@@ -0,0 +1,26 @@
package parsers
import (
// "fmt"
engine "github.com/tgckpg/mmqlengine/mmql/engine"
stmtd "github.com/tgckpg/mmqlengine/mmql/statements"
)
/*
EXPECT: [NAME]
OR
EXPECT: [FUNCTION]( ...params )
*/
func FinancialInstrumentStatement( lexer *engine.Lexer ) ( istmt stmtd.IStatement, err error ) {
stmt := stmtd.FinancialInstrumentStatement{}
name, err := lexer.ReadAlpha()
if err != nil {
return
}
stmt.Name = name
istmt = stmt
return
}