Parsing values, very incomplete for now (identifiers WIP).

mess
Karchnu 2020-12-18 01:31:39 +01:00
parent c887e2d786
commit 4f6891c4ab
2 changed files with 59 additions and 24 deletions

View File

@ -21,10 +21,11 @@ pub const Node = struct {
};
pub const PropertyValue = union {
string: [] const u8, // String.
integer: u64, // Num (integer).
float: f64, // Num (float).
reference: *u8, // Reference to another property (property binding).
// nil: null,
string: [] const u8, // String.
integer: u64, // Num (integer).
float: f64, // Num (float).
reference: [] const u8, // Reference to another property (property binding).
};
pub const Root = struct {

View File

@ -17,6 +17,9 @@ const lexer = @import("tokenizer.zig");
const Token = lexer.Token;
const Tokenizer = lexer.Tokenizer;
const cs = @import("common-structures.zig");
const PropertyValue = cs.PropertyValue;
pub const Error = error{ParseError} || Allocator.Error;
/// Result should be freed with tree.deinit() when there are
@ -185,9 +188,9 @@ const Parser = struct {
p.parseDefine() catch |err| switch(err) {
// Propagate memory errors.
error.OutOfMemory => { return (error.OutOfMemory); },
error.ParseError => {
continue;
}
error.InvalidCharacter => continue,
error.Overflow => continue,
error.ParseError => continue,
}; // |normal_value| { stuff; to; do; }
},
@ -197,6 +200,8 @@ const Parser = struct {
p.parseClass() catch |err| switch(err) {
// Propagate memory errors.
error.OutOfMemory => { return (error.OutOfMemory); },
error.InvalidCharacter => continue,
error.Overflow => continue,
error.ParseError => {
p.say("we catched a ParseError on token: {}\n"
, .{p.giveTokenContent(p.tok_i)});
@ -293,6 +298,7 @@ const Parser = struct {
.Identifier => {
const following = p.nextToken();
switch (p.token_ids[following]) {
// Class header (with or without id).
.LParen,
.LBrace => {
@ -327,10 +333,8 @@ const Parser = struct {
},
.Keyword_property => {
p.say("Reading a property\n", .{});
p.putBackToken(token);
try p.parseProperty();
p.say("Done reading a property\n", .{});
continue;
},
@ -357,26 +361,56 @@ const Parser = struct {
const end_of_class = try p.expectToken(.RBrace);
}
// A property value can either be a simple value,
// or a reference (for property binding stuff).
// Simple values are copied and casted into the real type.
// For a reference, we keep a copy of the string representation.
fn parseValue(p: *Parser) !PropertyValue {
while(true) {
const token = p.nextToken();
switch (p.token_ids[token]) {
// .Keyword_null => {
// return PropertyValue{.nil};
// },
.StringLiteral => {
return PropertyValue{.string = p.giveTokenContent(token)};
},
.IntegerLiteral => {
return PropertyValue{
.integer = try std.fmt.parseInt(u64, p.giveTokenContent(token), 10)
};
},
.FloatLiteral => {
// p.say("property: {} {} = {}\n"
// , .{p.giveTokenContent(class_name)
// , p.giveTokenContent(attribute_name)
// , p.giveTokenContent(id_value)});
return PropertyValue{
.float = try std.fmt.parseFloat(f64, p.giveTokenContent(token))
};
},
.Identifier => {
// Loop over identifier and points.
return error.ParseError;
// p.putBackToken(token);
// // TODO: do the loop
// const string: []const u8 = p.giveStringFromReference();
},
else => {
return error.ParseError;
}
}
}
}
fn parseProperty(p: *Parser) !void {
const property = try p.expectToken(.Keyword_property);
const class_name = try p.expectToken(.Identifier);
const attribute_name = try p.expectToken(.Identifier);
const colon = try p.expectToken(.Colon);
const id_value = p.nextToken();
switch (p.token_ids[id_value]) {
.Keyword_null,
.StringLiteral,
.IntegerLiteral,
.FloatLiteral => {
p.say("property: {} {} = {}\n"
, .{p.giveTokenContent(class_name), p.giveTokenContent(attribute_name), p.giveTokenContent(id_value)});
return ;
// return Assignment{.id_attribute = ia, .id_value = id_value};
},
else => {
return error.ParseError;
}
}
const value: PropertyValue = try p.parseValue();
std.debug.print("{}\n", .{value});
}