Implement more features (WIP)
This commit is contained in:
parent
8433736096
commit
508ed37040
@ -180,8 +180,8 @@ func compileExpressionWAT(expr Expression, block Block) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return "local.get $" + strconv.Itoa(block.Locals[ref.Variable].Index) + "\n" + cast, nil
|
return "local.get $" + strconv.Itoa(block.Locals[ref.Variable].Index) + "\n" + cast, nil
|
||||||
case Expression_Arithmetic:
|
case Expression_Binary:
|
||||||
arith := expr.Value.(ArithmeticExpression)
|
arith := expr.Value.(BinaryExpression)
|
||||||
|
|
||||||
log.Printf("%+#v", arith)
|
log.Printf("%+#v", arith)
|
||||||
|
|
||||||
@ -228,6 +228,8 @@ func compileExpressionWAT(expr Expression, block Block) (string, error) {
|
|||||||
op = getPrimitiveWATType(exprType) + ".div_" + suffix + "\n"
|
op = getPrimitiveWATType(exprType) + ".div_" + suffix + "\n"
|
||||||
case Arithmetic_Mod:
|
case Arithmetic_Mod:
|
||||||
op = getPrimitiveWATType(exprType) + ".rem_" + suffix + "\n"
|
op = getPrimitiveWATType(exprType) + ".rem_" + suffix + "\n"
|
||||||
|
default:
|
||||||
|
panic("operation not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
return watLeft + castLeft + watRight + castRight + op + getTypeCast(exprType), nil
|
return watLeft + castLeft + watRight + castRight + op + getTypeCast(exprType), nil
|
||||||
@ -319,7 +321,7 @@ func compileStatementWAT(stmt Statement, block Block) (string, error) {
|
|||||||
return wat + "local.set $" + strconv.Itoa(block.Locals[dlv.Variable].Index) + "\n", nil
|
return wat + "local.set $" + strconv.Itoa(block.Locals[dlv.Variable].Index) + "\n", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", nil
|
panic("stmt not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileBlockWAT(block Block) (string, error) {
|
func compileBlockWAT(block Block) (string, error) {
|
||||||
|
@ -2,7 +2,11 @@ u64 add(u8 a, u8 b) {
|
|||||||
return add(a - 1u8, a);
|
return add(a - 1u8, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 addわ(u64 a, u64 b) {
|
u64 add2(u64 a, u64 b) {
|
||||||
|
if(a == b) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
120
lexer.go
120
lexer.go
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -21,7 +22,7 @@ const (
|
|||||||
|
|
||||||
type Keyword uint32
|
type Keyword uint32
|
||||||
|
|
||||||
var Keywords []string = []string{"import", "void", "return", "true", "false"}
|
var Keywords []string = []string{"import", "void", "return", "true", "false", "if", "else"}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Keyword_Import Keyword = iota
|
Keyword_Import Keyword = iota
|
||||||
@ -29,6 +30,8 @@ const (
|
|||||||
Keyword_Return
|
Keyword_Return
|
||||||
Keyword_True
|
Keyword_True
|
||||||
KeyWord_False
|
KeyWord_False
|
||||||
|
Keyword_If
|
||||||
|
Keyword_Else
|
||||||
)
|
)
|
||||||
|
|
||||||
type Separator uint32
|
type Separator uint32
|
||||||
@ -46,7 +49,7 @@ const (
|
|||||||
|
|
||||||
type Operator uint32
|
type Operator uint32
|
||||||
|
|
||||||
var Operators []rune = []rune{'=', '>', '<', '!', '+', '-', '*', '/', '%'}
|
var Operators []string = []string{"=", ">", "<", "!", "+", "-", "*", "/", "%", "==", ">=", "<=", "!=", "+=", "-=", "*=", "/=", "%="}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Operator_Equals Operator = iota
|
Operator_Equals Operator = iota
|
||||||
@ -58,6 +61,15 @@ const (
|
|||||||
Operator_Multiply
|
Operator_Multiply
|
||||||
Operator_Divide
|
Operator_Divide
|
||||||
Operator_Modulo
|
Operator_Modulo
|
||||||
|
Operator_EqualsEquals
|
||||||
|
Operator_GreaterEquals
|
||||||
|
Operator_LessEquals
|
||||||
|
Operator_NotEquals
|
||||||
|
Operator_PlusEquals
|
||||||
|
Operator_MinusEquals
|
||||||
|
Operator_MultiplyEquals
|
||||||
|
Operator_DivideEquals
|
||||||
|
Operator_ModuloEquals
|
||||||
)
|
)
|
||||||
|
|
||||||
type LiteralType uint32
|
type LiteralType uint32
|
||||||
@ -98,6 +110,30 @@ func (l *Lexer) peekRune() *rune {
|
|||||||
return &l.Runes[0]
|
return &l.Runes[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *Lexer) tryOperator() Operator {
|
||||||
|
var foundOp Operator = InvalidValue
|
||||||
|
var foundOpLen int = 0
|
||||||
|
|
||||||
|
str := string(l.Runes)
|
||||||
|
for i, operator := range Operators {
|
||||||
|
operatorLen := len([]rune(operator))
|
||||||
|
if operatorLen <= foundOpLen {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(str, operator) {
|
||||||
|
foundOp = Operator(i)
|
||||||
|
foundOpLen = len([]rune(operator))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < foundOpLen; i++ {
|
||||||
|
l.nextRune()
|
||||||
|
}
|
||||||
|
|
||||||
|
return foundOp
|
||||||
|
}
|
||||||
|
|
||||||
func (l *Lexer) nextRune() *rune {
|
func (l *Lexer) nextRune() *rune {
|
||||||
if len(l.Runes) == 0 {
|
if len(l.Runes) == 0 {
|
||||||
return nil
|
return nil
|
||||||
@ -145,12 +181,12 @@ func (l *Lexer) stringLiteral() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: maybe this method should directly return LexToken
|
// TODO: maybe this method should directly return LexToken
|
||||||
func (l *Lexer) nextToken() (string, error) {
|
func (l *Lexer) nextToken() (*LexToken, error) {
|
||||||
// Skip whitespace
|
// Skip whitespace
|
||||||
for {
|
for {
|
||||||
r := l.peekRune()
|
r := l.peekRune()
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return "", nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !slices.Contains(Whitespace, *r) {
|
if !slices.Contains(Whitespace, *r) {
|
||||||
@ -164,55 +200,40 @@ func (l *Lexer) nextToken() (string, error) {
|
|||||||
|
|
||||||
r := l.peekRune()
|
r := l.peekRune()
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return "", nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if *r == '"' {
|
if *r == '"' {
|
||||||
literal, err := l.stringLiteral()
|
literal, err := l.stringLiteral()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return "\"" + literal + "\"", nil
|
return &LexToken{Type: Type_Literal, Position: l.LastTokenPosition, Value: Literal{Type: Literal_String, Primitive: InvalidValue, Value: literal}}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
op := l.tryOperator()
|
||||||
|
if op != InvalidValue {
|
||||||
|
return &LexToken{Type: Type_Operator, Position: l.LastTokenPosition, Value: op}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
token := ""
|
token := ""
|
||||||
for {
|
for {
|
||||||
r := l.peekRune()
|
r := l.peekRune()
|
||||||
if r == nil || slices.Contains(Whitespace, *r) || slices.Contains(Separators, *r) || slices.Contains(Operators, *r) {
|
if r == nil || slices.Contains(Whitespace, *r) || slices.Contains(Separators, *r) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
token += string(*l.nextRune())
|
token += string(*l.nextRune())
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(token) == 0 && len(l.Runes) != 0 {
|
if len(token) == 0 {
|
||||||
return string(*l.nextRune()), nil
|
if len(l.Runes) == 0 {
|
||||||
}
|
println("E3")
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
return token, nil
|
token = string(*l.nextRune())
|
||||||
}
|
|
||||||
|
|
||||||
func parseNumber(raw string, numberType PrimitiveType) (any, error) {
|
|
||||||
// TODO: return compiler errors
|
|
||||||
if isSignedInt(numberType) {
|
|
||||||
return strconv.ParseInt(raw, 10, getBits(numberType))
|
|
||||||
}
|
|
||||||
|
|
||||||
if isUnsignedInt(numberType) {
|
|
||||||
return strconv.ParseUint(raw, 10, getBits(numberType))
|
|
||||||
}
|
|
||||||
|
|
||||||
if isFloatingPoint(numberType) {
|
|
||||||
return strconv.ParseFloat(raw, getBits(numberType))
|
|
||||||
}
|
|
||||||
|
|
||||||
panic("Unhandled type (" + strconv.FormatUint(uint64(numberType), 10) + ") in parseNumber()")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lexer) parseToken(token string) (*LexToken, error) {
|
|
||||||
if strings.HasPrefix(token, "\"") {
|
|
||||||
return &LexToken{Type: Type_Literal, Position: l.LastTokenPosition, Value: Literal{Type: Literal_String, Primitive: InvalidValue, Value: token[1 : len(token)-1]}}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
runes := []rune(token)
|
runes := []rune(token)
|
||||||
@ -254,10 +275,6 @@ func (l *Lexer) parseToken(token string) (*LexToken, error) {
|
|||||||
if idx := slices.Index(Separators, runes[0]); idx != -1 {
|
if idx := slices.Index(Separators, runes[0]); idx != -1 {
|
||||||
return &LexToken{Type: Type_Separator, Position: l.LastTokenPosition, Value: Separator(idx)}, nil
|
return &LexToken{Type: Type_Separator, Position: l.LastTokenPosition, Value: Separator(idx)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if idx := slices.Index(Operators, runes[0]); idx != -1 {
|
|
||||||
return &LexToken{Type: Type_Operator, Position: l.LastTokenPosition, Value: Operator(idx)}, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if idx := slices.Index(Keywords, token); idx != -1 {
|
if idx := slices.Index(Keywords, token); idx != -1 {
|
||||||
@ -267,6 +284,23 @@ func (l *Lexer) parseToken(token string) (*LexToken, error) {
|
|||||||
return &LexToken{Type: Type_Identifier, Position: l.LastTokenPosition, Value: token}, nil
|
return &LexToken{Type: Type_Identifier, Position: l.LastTokenPosition, Value: token}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseNumber(raw string, numberType PrimitiveType) (any, error) {
|
||||||
|
// TODO: return compiler errors
|
||||||
|
if isSignedInt(numberType) {
|
||||||
|
return strconv.ParseInt(raw, 10, getBits(numberType))
|
||||||
|
}
|
||||||
|
|
||||||
|
if isUnsignedInt(numberType) {
|
||||||
|
return strconv.ParseUint(raw, 10, getBits(numberType))
|
||||||
|
}
|
||||||
|
|
||||||
|
if isFloatingPoint(numberType) {
|
||||||
|
return strconv.ParseFloat(raw, getBits(numberType))
|
||||||
|
}
|
||||||
|
|
||||||
|
panic("Unhandled type (" + strconv.FormatUint(uint64(numberType), 10) + ") in parseNumber()")
|
||||||
|
}
|
||||||
|
|
||||||
func lexer(program string) ([]LexToken, error) {
|
func lexer(program string) ([]LexToken, error) {
|
||||||
var tokens []LexToken
|
var tokens []LexToken
|
||||||
|
|
||||||
@ -274,20 +308,16 @@ func lexer(program string) ([]LexToken, error) {
|
|||||||
|
|
||||||
for {
|
for {
|
||||||
token, err := lexer.nextToken()
|
token, err := lexer.nextToken()
|
||||||
|
log.Printf("%+#v %+#v", token, err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(token) == 0 {
|
if token == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
lexToken, err := lexer.parseToken(token)
|
tokens = append(tokens, *token)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
tokens = append(tokens, *lexToken)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tokens, nil
|
return tokens, nil
|
||||||
|
153
parser.go
153
parser.go
@ -39,6 +39,7 @@ const (
|
|||||||
Statement_Block
|
Statement_Block
|
||||||
Statement_Return
|
Statement_Return
|
||||||
Statement_DeclareLocalVariable
|
Statement_DeclareLocalVariable
|
||||||
|
Statement_If
|
||||||
)
|
)
|
||||||
|
|
||||||
type Statement struct {
|
type Statement struct {
|
||||||
@ -65,13 +66,19 @@ type DeclareLocalVariableStatement struct {
|
|||||||
Initializer *Expression
|
Initializer *Expression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type IfStatement struct {
|
||||||
|
Condition Expression
|
||||||
|
ConditionalBlock Block
|
||||||
|
ElseBlock *Block
|
||||||
|
}
|
||||||
|
|
||||||
type ExpressionType uint32
|
type ExpressionType uint32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Expression_Assignment ExpressionType = iota
|
Expression_Assignment ExpressionType = iota
|
||||||
Expression_Literal
|
Expression_Literal
|
||||||
Expression_VariableReference
|
Expression_VariableReference
|
||||||
Expression_Arithmetic
|
Expression_Binary
|
||||||
Expression_Tuple
|
Expression_Tuple
|
||||||
Expression_FunctionCall
|
Expression_FunctionCall
|
||||||
Expression_Negate
|
Expression_Negate
|
||||||
@ -105,9 +112,16 @@ const (
|
|||||||
Arithmetic_Mul
|
Arithmetic_Mul
|
||||||
Arithmetic_Div
|
Arithmetic_Div
|
||||||
Arithmetic_Mod
|
Arithmetic_Mod
|
||||||
|
Arithmetic_Greater
|
||||||
|
Arithmetic_Less
|
||||||
|
Arithmetic_GreaterEquals
|
||||||
|
Arithmetic_LessEquals
|
||||||
|
Arithmetic_LogicalNot
|
||||||
|
Arithmetic_NotEquals
|
||||||
|
Arithmetic_Equals
|
||||||
)
|
)
|
||||||
|
|
||||||
type ArithmeticExpression struct {
|
type BinaryExpression struct {
|
||||||
Operation ArithmeticOperation
|
Operation ArithmeticOperation
|
||||||
Left Expression
|
Left Expression
|
||||||
Right Expression
|
Right Expression
|
||||||
@ -502,23 +516,7 @@ func (p *Parser) tryMultiplicativeExpression() (*Expression, error) {
|
|||||||
return nil, p.error("expected expression")
|
return nil, p.error("expected expression")
|
||||||
}
|
}
|
||||||
|
|
||||||
var operation ArithmeticOperation
|
left = &Expression{Type: Expression_Binary, Value: BinaryExpression{Operation: getArithmeticOperation(*op), Left: *left, Right: *right}, Position: left.Position}
|
||||||
switch *op {
|
|
||||||
case Operator_Multiply:
|
|
||||||
operation = Arithmetic_Mul
|
|
||||||
case Operator_Divide:
|
|
||||||
operation = Arithmetic_Div
|
|
||||||
case Operator_Plus:
|
|
||||||
operation = Arithmetic_Add
|
|
||||||
case Operator_Minus:
|
|
||||||
operation = Arithmetic_Sub
|
|
||||||
case Operator_Modulo:
|
|
||||||
fallthrough
|
|
||||||
default:
|
|
||||||
operation = Arithmetic_Mod
|
|
||||||
}
|
|
||||||
|
|
||||||
left = &Expression{Type: Expression_Arithmetic, Value: ArithmeticExpression{Operation: operation, Left: *left, Right: *right}, Position: left.Position}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,23 +549,86 @@ func (p *Parser) tryAdditiveExpression() (*Expression, error) {
|
|||||||
return nil, p.error("expected expression")
|
return nil, p.error("expected expression")
|
||||||
}
|
}
|
||||||
|
|
||||||
var operation ArithmeticOperation
|
left = &Expression{Type: Expression_Binary, Value: BinaryExpression{Operation: getArithmeticOperation(*op), Left: *left, Right: *right}, Position: left.Position}
|
||||||
if *op == Operator_Plus {
|
|
||||||
operation = Arithmetic_Add
|
|
||||||
} else {
|
|
||||||
operation = Arithmetic_Sub
|
|
||||||
}
|
|
||||||
|
|
||||||
left = &Expression{Type: Expression_Arithmetic, Value: ArithmeticExpression{Operation: operation, Left: *left, Right: *right}, Position: left.Position}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) tryArithmeticExpression() (*Expression, error) {
|
func (p *Parser) tryRelationalExpression() (*Expression, error) {
|
||||||
return p.tryAdditiveExpression()
|
left, err := p.tryAdditiveExpression()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if left == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
op, err := p.tryOperator(Operator_Less, Operator_Greater, Operator_LessEquals, Operator_GreaterEquals)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if op == nil {
|
||||||
|
return left, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
right, err := p.tryAdditiveExpression()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if right == nil {
|
||||||
|
return nil, p.error("expected expression")
|
||||||
|
}
|
||||||
|
|
||||||
|
left = &Expression{Type: Expression_Binary, Value: BinaryExpression{Operation: getArithmeticOperation(*op), Left: *left, Right: *right}, Position: left.Position}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parser) tryEqualityExpression() (*Expression, error) {
|
||||||
|
left, err := p.tryRelationalExpression()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if left == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
op, err := p.tryOperator(Operator_EqualsEquals, Operator_NotEquals)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if op == nil {
|
||||||
|
return left, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
right, err := p.tryRelationalExpression()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if right == nil {
|
||||||
|
return nil, p.error("expected expression")
|
||||||
|
}
|
||||||
|
|
||||||
|
left = &Expression{Type: Expression_Binary, Value: BinaryExpression{Operation: getArithmeticOperation(*op), Left: *left, Right: *right}, Position: left.Position}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parser) tryBinaryExpression() (*Expression, error) {
|
||||||
|
return p.tryEqualityExpression()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) tryExpression() (*Expression, error) {
|
func (p *Parser) tryExpression() (*Expression, error) {
|
||||||
return p.tryArithmeticExpression()
|
return p.tryBinaryExpression()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parser) expectExpression() (*Expression, error) {
|
||||||
|
return p.expect(p.tryExpression, "expected expression")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) tryTupleExpression() (*Expression, error) {
|
func (p *Parser) tryTupleExpression() (*Expression, error) {
|
||||||
@ -698,6 +759,38 @@ func (p *Parser) expectStatement() (*Statement, error) {
|
|||||||
return &Statement{Type: Statement_Return, Value: ReturnStatement{Value: expr}, Position: token.Position}, nil
|
return &Statement{Type: Statement_Return, Value: ReturnStatement{Value: expr}, Position: token.Position}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if token.Type == Type_Keyword && token.Value.(Keyword) == Keyword_If {
|
||||||
|
p.nextToken()
|
||||||
|
|
||||||
|
_, err := p.expectSeparator(Separator_OpenParen)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cond, err := p.expectExpression()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = p.expectSeparator(Separator_CloseParen)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
conditionalBlock, err := p.expectBlock()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tok := p.peekToken()
|
||||||
|
if tok == nil || tok.Type != Type_Keyword || tok.Value.(Keyword) != Keyword_Else {
|
||||||
|
return &Statement{Type: Statement_If, Value: IfStatement{Condition: *cond, ConditionalBlock: *conditionalBlock, ElseBlock: nil}, Position: token.Position}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
p.nextToken()
|
||||||
|
// TODO: else block
|
||||||
|
}
|
||||||
|
|
||||||
if token.Type == Type_Separator && token.Value.(Separator) == Separator_OpenCurly {
|
if token.Type == Type_Separator && token.Value.(Separator) == Separator_OpenCurly {
|
||||||
block, err := p.expectBlock()
|
block, err := p.expectBlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
40
types.go
40
types.go
@ -101,3 +101,43 @@ func getPrimitiveTypeByName(name string) (PrimitiveType, error) {
|
|||||||
|
|
||||||
return PrimitiveType(idx), nil
|
return PrimitiveType(idx), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isAssigmentOperator(operator Operator) bool {
|
||||||
|
switch operator {
|
||||||
|
case Operator_Equals, Operator_PlusEquals, Operator_MinusEquals, Operator_MultiplyEquals, Operator_DivideEquals, Operator_ModuloEquals:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getArithmeticOperation(operator Operator) ArithmeticOperation {
|
||||||
|
switch operator {
|
||||||
|
case Operator_Greater:
|
||||||
|
return Arithmetic_Greater
|
||||||
|
case Operator_Less:
|
||||||
|
return Arithmetic_Less
|
||||||
|
case Operator_Not:
|
||||||
|
return Arithmetic_LogicalNot
|
||||||
|
case Operator_Plus, Operator_PlusEquals:
|
||||||
|
return Arithmetic_Add
|
||||||
|
case Operator_Minus, Operator_MinusEquals:
|
||||||
|
return Arithmetic_Sub
|
||||||
|
case Operator_Multiply, Operator_MultiplyEquals:
|
||||||
|
return Arithmetic_Mul
|
||||||
|
case Operator_Divide, Operator_DivideEquals:
|
||||||
|
return Arithmetic_Div
|
||||||
|
case Operator_Modulo, Operator_ModuloEquals:
|
||||||
|
return Arithmetic_Mod
|
||||||
|
case Operator_EqualsEquals:
|
||||||
|
return Arithmetic_Equals
|
||||||
|
case Operator_GreaterEquals:
|
||||||
|
return Arithmetic_GreaterEquals
|
||||||
|
case Operator_LessEquals:
|
||||||
|
return Arithmetic_LessEquals
|
||||||
|
case Operator_NotEquals:
|
||||||
|
return Arithmetic_NotEquals
|
||||||
|
default:
|
||||||
|
return InvalidValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -117,8 +117,8 @@ func (v *Validator) validatePotentiallyVoidExpression(expr *Expression, block *B
|
|||||||
}
|
}
|
||||||
|
|
||||||
expr.ValueType = &local.Type
|
expr.ValueType = &local.Type
|
||||||
case Expression_Arithmetic:
|
case Expression_Binary:
|
||||||
arithmethic := expr.Value.(ArithmeticExpression)
|
arithmethic := expr.Value.(BinaryExpression)
|
||||||
|
|
||||||
errors = append(errors, v.validateExpression(&arithmethic.Left, block)...)
|
errors = append(errors, v.validateExpression(&arithmethic.Left, block)...)
|
||||||
errors = append(errors, v.validateExpression(&arithmethic.Right, block)...)
|
errors = append(errors, v.validateExpression(&arithmethic.Right, block)...)
|
||||||
|
Loading…
Reference in New Issue
Block a user