string ancora un po' rustiche
This commit is contained in:
@@ -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
32
lexer.v
@@ -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++
|
||||||
|
|||||||
8
parser.v
8
parser.v
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user