mirror of
https://github.com/hanzoai/numscript.git
synced 2026-10-30 18:26:57 +00:00
Modules declare go 1.27.1 and the build images follow. go fix applied the modernizers, and the interpreter's parseArg, evaluateExprAs and evaluateOptExprAs are now generic methods on the parser and program state they take. omitzero is not applied, since it changes what the JSON says. Co-Authored-By: Claude Opus 5 <[email protected]>
158 lines
3.0 KiB
Go
158 lines
3.0 KiB
Go
package interpreter
|
|
|
|
import (
|
|
"math/big"
|
|
|
|
"github.com/formancehq/numscript/internal/flags"
|
|
"github.com/formancehq/numscript/internal/parser"
|
|
)
|
|
|
|
func overdraft(
|
|
s *programState,
|
|
r parser.Range,
|
|
args []Value,
|
|
) (*Monetary, InterpreterError) {
|
|
err := s.checkFeatureFlag(flags.ExperimentalOverdraftFunctionFeatureFlag)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// TODO more precise args range location
|
|
p := NewArgsParser(args)
|
|
account := p.parseArg(r, expectAccount)
|
|
asset := p.parseArg(r, expectAsset)
|
|
err = p.parse()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
balance_, err := getBalance(s, *account, *asset)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
balanceIsPositive := balance_.Cmp(big.NewInt(0)) == 1
|
|
if balanceIsPositive {
|
|
return &Monetary{
|
|
Amount: NewMonetaryInt(0),
|
|
Asset: Asset(*asset),
|
|
}, nil
|
|
}
|
|
|
|
overdraft := new(big.Int).Neg(balance_)
|
|
return &Monetary{
|
|
Amount: MonetaryInt(*overdraft),
|
|
Asset: Asset(*asset),
|
|
}, nil
|
|
}
|
|
|
|
func meta(
|
|
s *programState,
|
|
rng parser.Range,
|
|
args []Value,
|
|
) (string, InterpreterError) {
|
|
// TODO more precise location
|
|
p := NewArgsParser(args)
|
|
account := p.parseArg(rng, expectAccount)
|
|
key := p.parseArg(rng, expectString)
|
|
err := p.parse()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
meta, fetchMetaErr := s.Store.GetAccountsMetadata(s.ctx, MetadataQuery{
|
|
*account: []string{*key},
|
|
})
|
|
if fetchMetaErr != nil {
|
|
return "", QueryMetadataError{WrappedError: fetchMetaErr}
|
|
}
|
|
s.CachedAccountsMeta = meta
|
|
|
|
// body
|
|
accountMeta := s.CachedAccountsMeta[*account]
|
|
value, ok := accountMeta[*key]
|
|
|
|
if !ok {
|
|
return "", MetadataNotFound{Account: *account, Key: *key, Range: rng}
|
|
}
|
|
|
|
return value, nil
|
|
}
|
|
|
|
func balance(
|
|
s *programState,
|
|
r parser.Range,
|
|
args []Value,
|
|
) (*Monetary, InterpreterError) {
|
|
// TODO more precise args range location
|
|
p := NewArgsParser(args)
|
|
account := p.parseArg(r, expectAccount)
|
|
asset := p.parseArg(r, expectAsset)
|
|
err := p.parse()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// body
|
|
|
|
balance, err := getBalance(s, *account, *asset)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if balance.Cmp(big.NewInt(0)) == -1 {
|
|
return nil, NegativeBalanceError{
|
|
Account: *account,
|
|
Amount: *balance,
|
|
}
|
|
}
|
|
|
|
balanceCopy := new(big.Int).Set(balance)
|
|
|
|
m := Monetary{
|
|
Asset: Asset(*asset),
|
|
Amount: MonetaryInt(*balanceCopy),
|
|
}
|
|
return &m, nil
|
|
}
|
|
|
|
func getAsset(
|
|
s *programState,
|
|
r parser.Range,
|
|
args []Value,
|
|
) (Value, InterpreterError) {
|
|
err := s.checkFeatureFlag(flags.ExperimentalGetAssetFunctionFeatureFlag)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
p := NewArgsParser(args)
|
|
mon := p.parseArg(r, expectMonetary)
|
|
err = p.parse()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return mon.Asset, nil
|
|
}
|
|
|
|
func getAmount(
|
|
s *programState,
|
|
r parser.Range,
|
|
args []Value,
|
|
) (Value, InterpreterError) {
|
|
err := s.checkFeatureFlag(flags.ExperimentalGetAmountFunctionFeatureFlag)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
p := NewArgsParser(args)
|
|
mon := p.parseArg(r, expectMonetary)
|
|
err = p.parse()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return mon.Amount, nil
|
|
}
|