Parse array types, Fix compiler errors
This commit is contained in:
parent
aef95b74cc
commit
99372dbc6a
53
lexer.go
53
lexer.go
@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -35,13 +36,15 @@ const (
|
||||
|
||||
type Separator uint32
|
||||
|
||||
var Separators []rune = []rune{'(', ')', '{', '}', ';', ','}
|
||||
var Separators []rune = []rune{'(', ')', '{', '}', '[', ']', ';', ','}
|
||||
|
||||
const (
|
||||
Separator_OpenParen Separator = iota
|
||||
Separator_CloseParen
|
||||
Separator_OpenCurly
|
||||
Separator_CloseCurly
|
||||
Separator_OpenSquare
|
||||
Separator_CloseSquare
|
||||
Separator_Semicolon
|
||||
Separator_Comma
|
||||
)
|
||||
@ -260,7 +263,7 @@ func (l *Lexer) nextToken() (*LexToken, error) {
|
||||
return nil, l.error("dot in non floating-point constant")
|
||||
}
|
||||
|
||||
number, err := parseNumber(rawNumber, numberType)
|
||||
number, err := l.parseNumber(rawNumber, numberType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -281,21 +284,55 @@ func (l *Lexer) nextToken() (*LexToken, error) {
|
||||
return &LexToken{Type: Type_Identifier, Position: l.LastTokenPosition, Value: token}, nil
|
||||
}
|
||||
|
||||
func parseNumber(raw string, numberType PrimitiveType) (any, error) {
|
||||
// TODO: return compiler errors
|
||||
func (l *Lexer) parseNumber(raw string, numberType PrimitiveType) (any, error) {
|
||||
if numberType == Primitive_Bool {
|
||||
return nil, l.error("bool not allowed as number suffix")
|
||||
}
|
||||
|
||||
base := 10
|
||||
if strings.HasPrefix(raw, "0x") {
|
||||
raw = raw[2:]
|
||||
base = 16
|
||||
} else if strings.HasPrefix(raw, "0o") {
|
||||
raw = raw[2:]
|
||||
base = 8
|
||||
} else if strings.HasPrefix(raw, "0b") {
|
||||
raw = raw[2:]
|
||||
base = 2
|
||||
}
|
||||
|
||||
if isSignedInt(numberType) {
|
||||
return strconv.ParseInt(raw, 10, getBits(numberType))
|
||||
num, err := strconv.ParseInt(raw, base, getBits(numberType))
|
||||
if err != nil {
|
||||
return nil, l.error("failed to parse literal: " + err.Error())
|
||||
}
|
||||
|
||||
return num, nil
|
||||
}
|
||||
|
||||
if isUnsignedInt(numberType) {
|
||||
return strconv.ParseUint(raw, 10, getBits(numberType))
|
||||
num, err := strconv.ParseUint(raw, base, getBits(numberType))
|
||||
if err != nil {
|
||||
return nil, l.error("failed to parse literal: " + err.Error())
|
||||
}
|
||||
|
||||
return num, nil
|
||||
}
|
||||
|
||||
if isFloatingPoint(numberType) {
|
||||
return strconv.ParseFloat(raw, getBits(numberType))
|
||||
if base != 10 {
|
||||
return nil, l.error("non base 10 float literals are not supported")
|
||||
}
|
||||
|
||||
panic("Unhandled type (" + strconv.FormatUint(uint64(numberType), 10) + ") in parseNumber()")
|
||||
num, err := strconv.ParseFloat(raw, getBits(numberType))
|
||||
if err != nil {
|
||||
return nil, l.error("failed to parse literal: " + err.Error())
|
||||
}
|
||||
|
||||
return num, nil
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("Unhandled type %s in parseNumber()", numberType))
|
||||
}
|
||||
|
||||
func lexer(program string) ([]LexToken, error) {
|
||||
|
39
parser.go
39
parser.go
@ -221,10 +221,10 @@ func (p *Parser) trySeparator(separators ...Separator) (*Separator, error) {
|
||||
return &sep, nil
|
||||
}
|
||||
|
||||
func (p *Parser) expectSeparator(separators ...Separator) (Separator, error) {
|
||||
func (p *Parser) expectSeparator(separators ...Separator) (*Separator, error) {
|
||||
sep, err := p.trySeparator(separators...)
|
||||
if err != nil {
|
||||
return InvalidValue, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if sep == nil {
|
||||
@ -233,10 +233,10 @@ func (p *Parser) expectSeparator(separators ...Separator) (Separator, error) {
|
||||
separatorNames = append(separatorNames, string(Separators[sep]))
|
||||
}
|
||||
|
||||
return InvalidValue, p.error("expected one of " + strings.Join(separatorNames, " "))
|
||||
return nil, p.error("expected one of " + strings.Join(separatorNames, " "))
|
||||
}
|
||||
|
||||
return *sep, nil
|
||||
return sep, nil
|
||||
}
|
||||
|
||||
func (p *Parser) tryOperator(operators ...Operator) (*Operator, error) {
|
||||
@ -293,14 +293,35 @@ func (p *Parser) tryType() (*Type, error) {
|
||||
if tok.Type == Type_Identifier {
|
||||
// TODO: array type
|
||||
|
||||
var theType Type
|
||||
|
||||
index := slices.Index(PRIMITIVE_TYPE_NAMES, tok.Value.(string))
|
||||
if index != -1 {
|
||||
*p = pCopy
|
||||
return &Type{Type: Type_Primitive, Value: PrimitiveType(index), Position: tok.Position}, nil
|
||||
theType = Type{Type: Type_Primitive, Value: PrimitiveType(index), Position: tok.Position}
|
||||
} else {
|
||||
theType = Type{Type: Type_Named, Value: tok.Value, Position: tok.Position}
|
||||
}
|
||||
|
||||
for {
|
||||
sep, err := pCopy.trySeparator(Separator_OpenSquare)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if sep == nil {
|
||||
break
|
||||
}
|
||||
|
||||
_, err = pCopy.expectSeparator(Separator_CloseSquare)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
theType = Type{Type: Type_Array, Value: ArrayType{ElementType: theType}, Position: theType.Position}
|
||||
}
|
||||
|
||||
*p = pCopy
|
||||
return &Type{Type: Type_Named, Value: tok.Value, Position: tok.Position}, nil
|
||||
return &theType, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
@ -339,13 +360,13 @@ func (p *Parser) expectTypeOrTupleType() (*Type, error) {
|
||||
|
||||
types = append(types, *parsedType)
|
||||
|
||||
var sep Separator
|
||||
var sep *Separator
|
||||
sep, err = p.expectSeparator(Separator_Comma, Separator_CloseParen)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if sep == Separator_CloseParen {
|
||||
if *sep == Separator_CloseParen {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ func (v *Validator) validateStatement(stmt *Statement, functionLocals *[]Local)
|
||||
}
|
||||
|
||||
if !isTypeExpandableTo(*ret.Value.ValueType, *v.currentFunction.ReturnType) {
|
||||
errors = append(errors, v.createError("expression type does not match function return type", ret.Value.Position))
|
||||
errors = append(errors, v.createError(fmt.Sprintf("cannot return value of type %s from function returning %s", *ret.Value.ValueType, *v.currentFunction.ReturnType), ret.Value.Position))
|
||||
}
|
||||
} else if v.currentFunction.ReturnType != nil {
|
||||
errors = append(errors, v.createError("missing return value", stmt.Position))
|
||||
|
Loading…
Reference in New Issue
Block a user