From: Mike Lowis Date: Thu, 9 Jan 2025 02:40:52 +0000 (-0500) Subject: finished record code generation X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=ce2298ed7a2a8f402866a92e9a43f8641c7839d5;p=proto%2Fcerise-c.git finished record code generation --- diff --git a/Int.c b/Int.c index af75d41..55de580 100644 --- a/Int.c +++ b/Int.c @@ -2,6 +2,7 @@ int Foo_Bar(); + typedef int Int_T; int Int_SumInts(int, int); diff --git a/cerise-c.m b/cerise-c.m index 5a46ca3..045c1a5 100644 --- a/cerise-c.m +++ b/cerise-c.m @@ -191,8 +191,8 @@ TestIfBlocks(){ TestRecords(){ def foo = new Records:Rec1 { foo = 42 } assert foo.foo == 42 -# set foo.foo = 43 -# assert foo.foo == 43 + set foo.foo = 43 + assert foo.foo == 43 } AddTwoNums(a : int, b : int) @@ -216,5 +216,6 @@ Main() TestGtEqOps() TestNeqOps() TestIfBlocks() + TestRecords() Int:SumInts(1,2) } diff --git a/lib/codegen.rb b/lib/codegen.rb index 78d7c8f..0d2a3c9 100644 --- a/lib/codegen.rb +++ b/lib/codegen.rb @@ -147,13 +147,13 @@ class Codegen puts "" end -# # output imported record declarations -# imported_mods.each do |mod| -# @syms[mod[:name]].type.exports.each do |name, val| -# define_sym(val) if val.kind == :type -# end -# puts "" -# end + # output imported record declarations + imported_mods.each do |mod| + @syms[mod[:name]].type.exports.each do |name, val| + define_sym(val) if val.kind == :type + end + puts "" + end # output this modules symbol declarations @syms.each { |name, val| declare_sym(val) } @@ -269,6 +269,13 @@ class Codegen else putln "#{type} #{result} = Array_Get(#{lvar}, #{rvar});" end + elsif v.op == "." + + lvar = emit(v.left) + result = mktemp(); + putln "#{type} #{result} = (#{lvar}->#{v.right.name});" + + else lvar = emit(v.left) rvar = emit(v.right) @@ -309,7 +316,10 @@ class Codegen putln "#{type} #{result} = (#{lvar} != #{rvar});" end when :new - putln "#{type} #{result} = 0;" + putln "#{type} #{result} = Record_Create(sizeof(#{type[0..-2]}));" + v.right.each do |field, value| + putln "#{result}->#{field} = #{emit(value)};" + end else raise "not implemented" end @@ -342,29 +352,20 @@ class Codegen @syms.add_sym(v.name.name, v.loc, :local, v.type, v.value) temp = emit(v.value) error v, "invalid local definition: #{v.name.name}" if not @locals.index(v.name.name) - -# if v.type.module.nil? -# sym = @syms[v.type.name].value || @syms[v.type.name].type -# else -# if type.module == @parser.module -# sym = @syms[v.type.name].type || @syms[v.type.name].value -# else -# sym = @syms[v.type.module].type.exports[v.type.name] -# sym = sym.type || sym.value -# end -# end -# is_record = sym.is_a?(Value::Type) and sym.form == :record - putln "#{type_to_s(v.value.type)} #{v.name.name} = #{temp};" end def emit_set(v) if v.name.is_a? IR::Op - error v, "not a valid array or hash access expression" if v.name.op != "[" + error v, "not a valid array or hash access expression" if (v.name.op != "[") && (v.name.op != ".") object = emit(v.name.left) key = emit(v.name.right) value = emit(v.value) - putln "Array_Set(#{object}, #{key}, #{value});" + if (v.name.op == ".") + putln "#{object}->#{v.name.right.name} = #{value};" + else + putln "Array_Set(#{object}, #{key}, #{value});" + end else temp = emit(v.value) error v, "invalid local definition: #{v.name.name}" if not @locals.index(v.name.name) diff --git a/lib/parser.rb b/lib/parser.rb index 7f3a4d0..830752e 100644 --- a/lib/parser.rb +++ b/lib/parser.rb @@ -364,6 +364,8 @@ class Parser name = identifier() if matches("[") name = array_or_hash_access(name) + elsif matches(".") + name = record_access(name) end expect ("=") value = expression() diff --git a/runtime.h b/runtime.h index b50568b..2cbc11a 100644 --- a/runtime.h +++ b/runtime.h @@ -50,7 +50,14 @@ static inline void Assert(char* file, int lineno, bool val) } } -/* Strings +/* Records + *************************************************/ +static inline void* Record_Create(size_t sz) +{ + return calloc(1, sz); +} + +/* Arrays *************************************************/ #pragma GCC diagnostic push