Add parsing int, float, and string literals
This commit is contained in:
parent
a47023fc95
commit
d445743200
|
@ -22,8 +22,15 @@ func (this *Parser) parseExpression () (entity.Expression, error) {
|
|||
// the very next token AKA the current one after parsing the
|
||||
// expression.
|
||||
// 3. Then, use the previously parsed expression and use it as the left
|
||||
// side, and go on to parse the right side. We need a more
|
||||
// 4. Repeat from step 2 if needed.
|
||||
// side, and go on to parse the right side. Assignment (=) is the
|
||||
// only infix expression where both left and right sides are
|
||||
// expressions, so it gets to call parseExpression() and recurse. The
|
||||
// implied associativity matters here.
|
||||
// 4. If not assignment, then this has to do with member access (the
|
||||
// right side is not an expression), so we repeat from step 2 in order
|
||||
// to chain member accesses and method calls. Step 2 will test
|
||||
// whether or not we need to continue repeating afterward. The
|
||||
// implied associativity matters here.
|
||||
// 5. Return the expression, whether it was directly parsed or is a tree
|
||||
// of infix operator(s).
|
||||
expression, err := this.parseExpressionRoot()
|
||||
|
@ -40,9 +47,9 @@ func (this *Parser) parseExpressionRoot () (entity.Expression, error) {
|
|||
case lexer.Ident: return this.parseExpressionRootIdent()
|
||||
case lexer.LBracket: // TODO
|
||||
case lexer.LParen: // TODO
|
||||
case lexer.Int: // TODO
|
||||
case lexer.Float: // TODO
|
||||
case lexer.String: // TODO
|
||||
case lexer.Int: return this.parseLiteralInt()
|
||||
case lexer.Float: return this.parseLiteralFloat()
|
||||
case lexer.String: return this.parseLiteralString()
|
||||
}
|
||||
panic(this.bug())
|
||||
}
|
||||
|
@ -55,6 +62,7 @@ func (this *Parser) parseExpressionRootIdent () (entity.Expression, error) {
|
|||
|
||||
this.next()
|
||||
if this.token.Is(lexer.Colon) {
|
||||
// Colon: declaration
|
||||
return this.parseDeclarationCore(pos, name)
|
||||
} else {
|
||||
switch name {
|
||||
|
@ -98,3 +106,42 @@ func (this *Parser) parseDeclarationCore (pos errors.Position, name string) (*en
|
|||
Ty: ty,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (this *Parser) parseLiteralInt () (*entity.LiteralInt, error) {
|
||||
err := this.expect(lexer.Int)
|
||||
if err != nil { return nil, err }
|
||||
defer this.next()
|
||||
|
||||
value, err := parseInteger(this.value())
|
||||
if err != nil { return nil, errors.Errorf(this.pos(), err.Error()) }
|
||||
|
||||
return &entity.LiteralInt {
|
||||
Position: this.pos(),
|
||||
Value: int(value), // TODO struct should store as int64
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (this *Parser) parseLiteralFloat () (*entity.LiteralFloat, error) {
|
||||
err := this.expect(lexer.Float)
|
||||
if err != nil { return nil, err }
|
||||
defer this.next()
|
||||
|
||||
value, err := parseFloat(this.value())
|
||||
if err != nil { return nil, errors.Errorf(this.pos(), err.Error()) }
|
||||
|
||||
return &entity.LiteralFloat {
|
||||
Position: this.pos(),
|
||||
Value: value,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (this *Parser) parseLiteralString () (*entity.LiteralString, error) {
|
||||
err := this.expect(lexer.String)
|
||||
if err != nil { return nil, err }
|
||||
defer this.next()
|
||||
|
||||
return &entity.LiteralString {
|
||||
Position: this.pos(),
|
||||
ValueUTF8: this.value(),
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package parser
|
||||
|
||||
import "strconv"
|
||||
import "git.tebibyte.media/sashakoshka/fspl/lexer"
|
||||
import "git.tebibyte.media/sashakoshka/fspl/entity"
|
||||
|
||||
|
@ -41,3 +42,31 @@ func (this *Parser) parseSignature () (*entity.Signature, error) {
|
|||
|
||||
return signature, nil
|
||||
}
|
||||
|
||||
func parseInteger (value string) (int64, error) {
|
||||
base := 10
|
||||
if len(value) >= 1 && value[0] == '0' {
|
||||
base = 8
|
||||
value = value[1:]
|
||||
if len(value) >= 1 {
|
||||
switch value[0] {
|
||||
case 'x':
|
||||
value = value[1:]
|
||||
base = 16
|
||||
case 'b':
|
||||
value = value[1:]
|
||||
base = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
integer, err := strconv.ParseInt(value, base, 64)
|
||||
if err != nil { return 0, err }
|
||||
return integer, nil
|
||||
}
|
||||
|
||||
func parseFloat (value string) (float64, error) {
|
||||
float, err := strconv.ParseFloat(value, 64)
|
||||
if err != nil { return 0, err }
|
||||
return float, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue