From: Michael D. Lowis Date: Mon, 4 Nov 2024 02:44:01 +0000 (-0500) Subject: added qualified_identifier rule X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=2c575b7740f67c58ebdf41db7caa488f907c8e79;p=proto%2Fcerise-c.git added qualified_identifier rule --- diff --git a/lib/parser.rb b/lib/parser.rb index a33731b..49f0532 100644 --- a/lib/parser.rb +++ b/lib/parser.rb @@ -218,7 +218,7 @@ class Parser if accept(:record) base_type = nil if accept("(") - base_type = identifier() + base_type = qualified_identifier() expect(")") end type = Value::Type.new(:record, {}, base_type, 0) @@ -258,9 +258,30 @@ class Parser args end + def qualified_identifier() + tok = expect(:ident) + varname = IR::Var.new(tok.pos, nil, tok.text.to_sym, nil) + if matches(".") + mod = syms[varname.name] + if mod.nil? + error("no such module: '#{varname.name}'") + end + if mod.kind != :module + error("accessing field in object that is neither a record nor a module") + end + tok = consume() + sym = mod.type.exports[tok.text.to_sym] + if not sym + error("module or record has no such field '#{tok.text}'") + end + varname = IR::Var.new(tok.pos, sym[:type], tok.text.to_sym, varname.name) + end + varname + end + def identifier() - name = expect(:ident) - IR::Var.new(name.pos, nil, name.text.to_sym) + tok = expect(:ident) + IR::Var.new(tok.pos, nil, tok.text.to_sym, nil) end def type_specifier() @@ -269,7 +290,7 @@ class Parser type = Value::Type.new(:array, nil, base_type, 0) expect("]") else - type = expect(:ident).text.to_sym + type = qualified_identifier() end type end @@ -485,20 +506,7 @@ class Parser elsif tok.type == :void IR::Const.new(tok.pos, :void, :void) elsif tok.type == :ident - varname = IR::Var.new(tok.pos, nil, tok.text.to_sym, nil) - if accept(".") - mod = syms[varname.name] - if mod.kind != :module - error("accessing field in object that is neither a record nor a module") - end - tok = consume() - sym = mod.type.exports[tok.text.to_sym] - if not sym - error("module or record has no such field '#{tok.text}'") - end - varname = IR::Var.new(tok.pos, sym[:type], tok.text.to_sym, varname.name) - end - varname + qualified_identifier() else error("invalid constant #{tok}") end