Added string literal to parser
This commit is contained in:
parent
496a8c5e78
commit
d0245e4375
@ -1,6 +1,7 @@
|
|||||||
package entity
|
package entity
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
import "unicode"
|
||||||
import "github.com/alecthomas/participle/v2/lexer"
|
import "github.com/alecthomas/participle/v2/lexer"
|
||||||
|
|
||||||
// LiteralInt specifies an integer value. It can be assigned to any type that is
|
// LiteralInt specifies an integer value. It can be assigned to any type that is
|
||||||
@ -42,6 +43,46 @@ func (this *LiteralFloat) String () string {
|
|||||||
return fmt.Sprint(this.Value)
|
return fmt.Sprint(this.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LiteralString specifies a string value. It takes on different data
|
||||||
|
// representations depending on what the base type of what it is assigned to is
|
||||||
|
// structurally equivalent to:
|
||||||
|
// - Integer: Single unicode code point. When assigning to an integer, the
|
||||||
|
// string literal may not be longer than one code point, and that code point
|
||||||
|
// must fit in the integer.
|
||||||
|
// - Slice of 8 bit integers: UTF-8 string.
|
||||||
|
// - Slice of 16 bit integers: UTF-16 string.
|
||||||
|
// - Slice of 32 bit (or larger) integers: UTF-32 string.
|
||||||
|
// - Array of integers: The same as slices of integers, but the string literal
|
||||||
|
// must fit inside of the array.
|
||||||
|
// - Byte pointer: Null-terminated UTF-8 string (AKA C-string).
|
||||||
|
// A string literal cannot be directly assigned to an interface because it
|
||||||
|
// contains no inherent type information. A value cast may be used for this
|
||||||
|
// purpose.
|
||||||
|
type LiteralString struct {
|
||||||
|
// Syntax
|
||||||
|
Pos lexer.Position
|
||||||
|
Value string `parser:" @String "`
|
||||||
|
|
||||||
|
// Semantics
|
||||||
|
Ty Type
|
||||||
|
}
|
||||||
|
func (*LiteralString) expression(){}
|
||||||
|
func (*LiteralString) statement(){}
|
||||||
|
func (this *LiteralString) Type () Type { return this.Ty }
|
||||||
|
func (this *LiteralString) String () string {
|
||||||
|
out := "'"
|
||||||
|
for _, char := range this.Value {
|
||||||
|
if char == '\'' {
|
||||||
|
out += "\\'"
|
||||||
|
} else if unicode.IsPrint(char) {
|
||||||
|
out += string(char)
|
||||||
|
} else {
|
||||||
|
out += fmt.Sprintf("\\%03o", char)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out + "'"
|
||||||
|
}
|
||||||
|
|
||||||
// LiteralArray is a composite array literal. It can contain any number of
|
// LiteralArray is a composite array literal. It can contain any number of
|
||||||
// values. It can be assigned to any array type that:
|
// values. It can be assigned to any array type that:
|
||||||
// 1. has an identical length, and
|
// 1. has an identical length, and
|
||||||
|
@ -149,9 +149,7 @@ func (this *fsplLexer) nextInternal () (token lexer.Token, err error) {
|
|||||||
err = this.nextRune()
|
err = this.nextRune()
|
||||||
if err != nil { return }
|
if err != nil { return }
|
||||||
|
|
||||||
println("NEW STRING")
|
|
||||||
for this.rune != '\'' {
|
for this.rune != '\'' {
|
||||||
println(string(this.rune))
|
|
||||||
if this.rune == '\\' {
|
if this.rune == '\\' {
|
||||||
var result rune
|
var result rune
|
||||||
result, err = this.escapeSequence()
|
result, err = this.escapeSequence()
|
||||||
|
@ -35,7 +35,8 @@ testString (test,
|
|||||||
[float]:F64 = 324.23409
|
[float]:F64 = 324.23409
|
||||||
[boolean]:Bool = true
|
[boolean]:Bool = true
|
||||||
[boolean2]:Bool = false
|
[boolean2]:Bool = false
|
||||||
[struct]:(x:Int y:(w:F64 z:F64)) = (x:1 y:(w:1.2 z:78.5))`,
|
[struct]:(x:Int y:(w:F64 z:F64)) = (x:1 y:(w:1.2 z:78.5))
|
||||||
|
[string]:String = 'hahah \'sup\005'`,
|
||||||
// input
|
// input
|
||||||
`
|
`
|
||||||
[int]:Int = 5
|
[int]:Int = 5
|
||||||
@ -43,6 +44,7 @@ testString (test,
|
|||||||
[boolean]:Bool = true
|
[boolean]:Bool = true
|
||||||
[boolean2]:Bool = false
|
[boolean2]:Bool = false
|
||||||
[struct]:(x:Int y:(w:F64 z:F64)) = (x: 1 y: (w: 1.2 z: 78.5))
|
[struct]:(x:Int y:(w:F64 z:F64)) = (x: 1 y: (w: 1.2 z: 78.5))
|
||||||
|
[string]:String = 'hahah \'sup\005'
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
109
parser/tree.go
109
parser/tree.go
@ -9,63 +9,64 @@ import flexer "git.tebibyte.media/sashakoshka/fspl/lexer"
|
|||||||
|
|
||||||
var parser = participle.MustBuild[Tree] (
|
var parser = participle.MustBuild[Tree] (
|
||||||
participle.Union[entity.TopLevel] (
|
participle.Union[entity.TopLevel] (
|
||||||
&entity.Function { },
|
new(entity.Function),
|
||||||
&entity.Typedef { },
|
new(entity.Typedef),
|
||||||
&entity.Method { }),
|
new(entity.Method)),
|
||||||
participle.Union[entity.Type] (
|
participle.Union[entity.Type] (
|
||||||
&entity.TypeNamed { },
|
new(entity.TypeNamed),
|
||||||
&entity.TypePointer { },
|
new(entity.TypePointer),
|
||||||
&entity.TypeInterface { },
|
new(entity.TypeInterface),
|
||||||
&entity.TypeStruct { },
|
new(entity.TypeStruct),
|
||||||
&entity.TypeArray { },
|
new(entity.TypeArray),
|
||||||
&entity.TypeSlice { }),
|
new(entity.TypeSlice)),
|
||||||
participle.Union[entity.Expression] (
|
participle.Union[entity.Expression] (
|
||||||
&entity.LiteralInt { },
|
new(entity.LiteralInt),
|
||||||
&entity.LiteralFloat { },
|
new(entity.LiteralFloat),
|
||||||
&entity.LiteralArray { },
|
new(entity.LiteralString),
|
||||||
&entity.LiteralStruct { },
|
new(entity.LiteralArray),
|
||||||
&entity.LiteralBoolean { },
|
new(entity.LiteralStruct),
|
||||||
&entity.Break { },
|
new(entity.LiteralBoolean),
|
||||||
&entity.Return { },
|
new(entity.Break),
|
||||||
&entity.IfElse { },
|
new(entity.Return),
|
||||||
&entity.Loop { },
|
new(entity.IfElse),
|
||||||
&entity.MethodCall { },
|
new(entity.Loop),
|
||||||
&entity.MemberAccess { },
|
new(entity.MethodCall),
|
||||||
&entity.Declaration { },
|
new(entity.MemberAccess),
|
||||||
&entity.Variable { },
|
new(entity.Declaration),
|
||||||
&entity.Subscript { },
|
new(entity.Variable),
|
||||||
&entity.Slice { },
|
new(entity.Subscript),
|
||||||
&entity.Dereference { },
|
new(entity.Slice),
|
||||||
&entity.Reference { },
|
new(entity.Dereference),
|
||||||
&entity.ValueCast { },
|
new(entity.Reference),
|
||||||
&entity.BitCast { },
|
new(entity.ValueCast),
|
||||||
&entity.Operation { },
|
new(entity.BitCast),
|
||||||
&entity.Call { },
|
new(entity.Operation),
|
||||||
&entity.Block { }),
|
new(entity.Call),
|
||||||
|
new(entity.Block)),
|
||||||
participle.Union[entity.Statement] (
|
participle.Union[entity.Statement] (
|
||||||
&entity.LiteralInt { },
|
new(entity.LiteralInt),
|
||||||
&entity.LiteralFloat { },
|
new(entity.LiteralFloat),
|
||||||
&entity.LiteralArray { },
|
new(entity.LiteralArray),
|
||||||
&entity.LiteralStruct { },
|
new(entity.LiteralStruct),
|
||||||
&entity.LiteralBoolean { },
|
new(entity.LiteralBoolean),
|
||||||
&entity.Break { },
|
new(entity.Break),
|
||||||
&entity.Return { },
|
new(entity.Return),
|
||||||
&entity.Assignment { },
|
new(entity.Assignment),
|
||||||
&entity.IfElse { },
|
new(entity.IfElse),
|
||||||
&entity.Loop { },
|
new(entity.Loop),
|
||||||
&entity.MethodCall { },
|
new(entity.MethodCall),
|
||||||
&entity.MemberAccess { },
|
new(entity.MemberAccess),
|
||||||
&entity.Declaration { },
|
new(entity.Declaration),
|
||||||
&entity.Variable { },
|
new(entity.Variable),
|
||||||
&entity.Subscript { },
|
new(entity.Subscript),
|
||||||
&entity.Slice { },
|
new(entity.Slice),
|
||||||
&entity.Dereference { },
|
new(entity.Dereference),
|
||||||
&entity.Reference { },
|
new(entity.Reference),
|
||||||
&entity.ValueCast { },
|
new(entity.ValueCast),
|
||||||
&entity.BitCast { },
|
new(entity.BitCast),
|
||||||
&entity.Operation { },
|
new(entity.Operation),
|
||||||
&entity.Call { },
|
new(entity.Call),
|
||||||
&entity.Block { }),
|
new(entity.Block)),
|
||||||
participle.UseLookahead(participle.MaxLookahead),
|
participle.UseLookahead(participle.MaxLookahead),
|
||||||
participle.Lexer(flexer.NewDefinition()))
|
participle.Lexer(flexer.NewDefinition()))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user