string ancora un po' rustiche

This commit is contained in:
uan
2026-02-05 22:30:50 +01:00
parent 078a300c1f
commit 1581ca4928
3 changed files with 35 additions and 11 deletions

View File

@@ -27,6 +27,7 @@ fn get_type_format(type string) string {
return match type { return match type {
'int', 'bool' {'d'} 'int', 'bool' {'d'}
'real' {'f'} 'real' {'f'}
'string' {'s'}
else {panic("invalid type to print")} else {panic("invalid type to print")}
} }
} }
@@ -45,6 +46,7 @@ fn (mut g Generator) get_c_type(typ string) string {
return match typ { return match typ {
'real' {'float'} 'real' {'float'}
'int' {'int32_t'} 'int' {'int32_t'}
'string' {'char*'}
else {typ} else {typ}
} }
} }
@@ -150,6 +152,9 @@ fn (mut g Generator) gen_expr(expr Expr) {
BoolLiteral { BoolLiteral {
g.out.write_string(expr.val.str()) g.out.write_string(expr.val.str())
} }
StringLiteral {
g.out.write_string('\"${expr.val}\"')
}
Variable { Variable {
g.out.write_string(mangle_var(expr.name)) g.out.write_string(mangle_var(expr.name))
} }
@@ -231,6 +236,7 @@ fn (mut g Generator) gen_c(program []Stmt) string {
g.out.writeln('#include <stdio.h>') g.out.writeln('#include <stdio.h>')
g.out.writeln('#include <stdbool.h>') g.out.writeln('#include <stdbool.h>')
g.out.writeln('#include <stdint.h>') g.out.writeln('#include <stdint.h>')
//g.out.writeln('typedef struct __one_string_builtin__ {\nchar* string;\nint len;\n} string;')
for stmt in program { for stmt in program {
g.gen_stmt(stmt) g.gen_stmt(stmt)
} }

32
lexer.v
View File

@@ -17,6 +17,7 @@ enum TokenType as u8 {
integer integer
real real
boolean boolean
string
identifier identifier
plus plus
minus minus
@@ -95,7 +96,7 @@ fn toktype_from_kw(kw string) TokenType {
return match kw { return match kw {
'let' {.kw_let} 'let' {.kw_let}
'const' {.kw_const} 'const' {.kw_const}
'void', 'real', 'bool', 'int' {.type} 'void', 'real', 'bool', 'int', 'string'{.type}
'if' {.kw_if} 'if' {.kw_if}
'else' {.kw_else} 'else' {.kw_else}
'for' {.kw_for} 'for' {.kw_for}
@@ -111,8 +112,8 @@ fn toktype_from_kw(kw string) TokenType {
fn is_delimiter(c u8, is_inside_number bool) bool { fn is_delimiter(c u8, is_inside_number bool) bool {
valid_chars := match is_inside_number { valid_chars := match is_inside_number {
true {" +-*/,;:%<>()[]{}=\n"} true {" +-*/,;:%<>()[]{}=\n\""}
false {". +-*/,;:%<>()[]{}=\n"} false {". +-*/,;:%<>()[]{}=\n\""}
} }
return valid_chars.contains(c.ascii_str()) return valid_chars.contains(c.ascii_str())
} }
@@ -124,7 +125,7 @@ fn is_real(str string) bool {
fn is_keyword(str string) bool { fn is_keyword(str string) bool {
return [ return [
"void", "int", "real", "bool", "if", "else", "for", "break", "fn", "return", "let", "const", "true", "false", "print", "class" "void", "int", "real", "bool", "string", "if", "else", "for", "break", "fn", "return", "let", "const", "true", "false", "print", "class"
].contains(str) ].contains(str)
} }
@@ -144,8 +145,18 @@ fn lex(input string) ?[]Token {
mut line := 1 mut line := 1
mut tokens := []Token{} mut tokens := []Token{}
mut is_inside_number := false mut is_inside_number := false
mut is_inside_string := false
for (right < input.len && left <= right) { for (right < input.len && left <= right) {
for is_inside_string {
right++
if input[right].ascii_str() == '\"' {
is_inside_string = false
right++
tokens << Token{.string, input.substr(left+1, right-1)}
left = right
}
}
is_inside_number = input[left].ascii_str().is_int() is_inside_number = input[left].ascii_str().is_int()
if input[right] == `\n` { if input[right] == `\n` {
line++ line++
@@ -158,14 +169,15 @@ fn lex(input string) ?[]Token {
} }
if is_delimiter(input[right], is_inside_number) && left == right { if is_delimiter(input[right], is_inside_number) && left == right {
if !input[right].is_space() { if !input[right].is_space() {
if input[right].ascii_str() == '\"' {is_inside_string = true; continue}
mut tok_str := input[right].ascii_str() mut tok_str := input[right].ascii_str()
if right + 1 < input.len { if right + 1 < input.len {
combined := input.substr(right, right + 2) combined := input.substr(right, right + 2)
if combined in ['==', '>=', '<=', '!=', '+=', '-=', '*=', '/=', '++', '--'] { if combined in ['==', '>=', '<=', '!=', '+=', '-=', '*=', '/=', '++', '--'] {
tok_str = combined tok_str = combined
right++ right++
}
} }
}
tokens << Token{toktype_from_delimiter(tok_str), tok_str} tokens << Token{toktype_from_delimiter(tok_str), tok_str}
} }
right++ right++

View File

@@ -115,7 +115,7 @@ fn (mut s SymbolTable) is_in_global_scope() bool {
// ------------------------------------------- Expressions // ------------------------------------------- Expressions
type Expr = VoidExpr | UnaryExpr | BinaryExpr | IntegerLiteral | RealLiteral | BoolLiteral | Variable | TypeExpr | Function | TypeCast | ParenExpr | PrintExpr | FnCall | ClassMember | ClassInstantiation | MemberAccess type Expr = VoidExpr | UnaryExpr | BinaryExpr | IntegerLiteral | RealLiteral | BoolLiteral | StringLiteral | Variable | TypeExpr | Function | TypeCast | ParenExpr | PrintExpr | FnCall | ClassMember | ClassInstantiation | MemberAccess
struct VoidExpr {} struct VoidExpr {}
@@ -142,6 +142,10 @@ struct BoolLiteral {
val bool val bool
} }
struct StringLiteral {
val string
}
struct Variable { struct Variable {
name string name string
} }
@@ -295,6 +299,7 @@ fn (mut p Parser) parse_primary() Expr {
.integer {IntegerLiteral{token.text.int()}} .integer {IntegerLiteral{token.text.int()}}
.real {RealLiteral{token.text.f32()}} .real {RealLiteral{token.text.f32()}}
.boolean {BoolLiteral{token.text == 'true'}} .boolean {BoolLiteral{token.text == 'true'}}
.string {StringLiteral{token.text}}
.kw_fn {Function{token.text}} .kw_fn {Function{token.text}}
.identifier {p.parse_ident(token.text)} .identifier {p.parse_ident(token.text)}
.type {p.parse_type(token.text)} .type {p.parse_type(token.text)}
@@ -461,6 +466,7 @@ fn (mut p Parser) get_expr_type(expr Expr) string {
IntegerLiteral {'int'} IntegerLiteral {'int'}
RealLiteral {'real'} RealLiteral {'real'}
BoolLiteral {'bool'} BoolLiteral {'bool'}
StringLiteral {'string'}
VoidExpr {'void'} VoidExpr {'void'}
TypeExpr {expr.name} TypeExpr {expr.name}
BinaryExpr { BinaryExpr {