Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve cli #15

Merged
merged 2 commits into from
Feb 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bench.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def setup() -> None:
for opt in optimization_levels:
subprocess.run(f"clang ./benchmark/llfib.ll -o llfib_{opt} -{opt}".split())

subprocess.run("python -m lythonc --compile ./benchmark/pyfib.py pyfib".split())
subprocess.run("python -m lythonc ./benchmark/pyfib.py -o pyfib".split())


def run_command(command: str) -> Tuple[str, float]:
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
only-include = ["src"]
sources = ["src"]

[tool.uv.sources]
lython = { workspace = true }
70 changes: 70 additions & 0 deletions source.py.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
@.str.0 = private unnamed_addr constant [14 x i8] c"\48\65\6c\6c\6f\2c\20\77\6f\72\6c\64\21\00", align 1
@.str.1 = private unnamed_addr constant [2 x i8] c"\61\00", align 1
@.str.2 = private unnamed_addr constant [2 x i8] c"\62\00", align 1
@.str.3 = private unnamed_addr constant [2 x i8] c"\63\00", align 1
@.str.4 = private unnamed_addr constant [5 x i8] c"\6b\65\79\31\00", align 1
@.str.5 = private unnamed_addr constant [5 x i8] c"\6b\65\79\32\00", align 1
@.str.6 = private unnamed_addr constant [5 x i8] c"\6b\65\79\33\00", align 1
@.str.7 = private unnamed_addr constant [5 x i8] c"\6b\65\79\31\00", align 1
attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" }
; ========== External runtime declarations ==========
declare void @print(ptr)

declare ptr @int2str(i32)
declare ptr @str2str(ptr)

declare ptr @create_string(ptr)

declare ptr @PyInt_FromI32(i32)
declare i32 @PyInt_AsI32(ptr)
declare ptr @PyDict_New(i32)
declare i32 @PyDict_SetItem(ptr, ptr, ptr)
declare ptr @PyDict_GetItem(ptr, ptr)
declare ptr @PyList_New(i32)
declare i32 @PyList_Append(ptr, ptr)
declare ptr @PyList_GetItem(ptr, i32)
declare void @GC_init()
%struct.String = type { i64, ptr } ; // length + data pointer


define i32 @main(i32 %argc, i8** %argv) {
entry:
call void @GC_init()
%t0 = call ptr @create_string(ptr @.str.0)
call void @print(ptr %t0)
%t1 = add i32 0, 0 ; discard return
%t2 = call ptr @PyList_New(i32 8)
%t3 = call ptr @PyInt_FromI32(i32 0)
call i32 @PyList_Append(ptr %t2, ptr %t3)
%t4 = call ptr @PyInt_FromI32(i32 1)
call i32 @PyList_Append(ptr %t2, ptr %t4)
%t5 = call ptr @PyInt_FromI32(i32 2)
call i32 @PyList_Append(ptr %t2, ptr %t5)
%t6 = call ptr @create_string(ptr @.str.1)
call i32 @PyList_Append(ptr %t2, ptr %t6)
%t7 = call ptr @create_string(ptr @.str.2)
call i32 @PyList_Append(ptr %t2, ptr %t7)
%t8 = call ptr @create_string(ptr @.str.3)
call i32 @PyList_Append(ptr %t2, ptr %t8)
%listvar = bitcast ptr %t2 to ptr ; assignment to listvar
%t9 = call ptr @PyDict_New(i32 8)
%t10 = call ptr @create_string(ptr @.str.4)
%t12 = call ptr @PyInt_FromI32(i32 1)
call i32 @PyDict_SetItem(ptr %t9, ptr %t10, ptr %t12)
%t13 = call ptr @create_string(ptr @.str.5)
%t15 = call ptr @PyInt_FromI32(i32 2)
call i32 @PyDict_SetItem(ptr %t9, ptr %t13, ptr %t15)
%t16 = call ptr @create_string(ptr @.str.6)
%t18 = call ptr @PyInt_FromI32(i32 3)
call i32 @PyDict_SetItem(ptr %t9, ptr %t16, ptr %t18)
%dictvar = bitcast ptr %t9 to ptr ; assignment to dictvar
%t19 = call ptr @PyList_GetItem(ptr %listvar, i32 3)
call void @print(ptr %t19)
%t20 = add i32 0, 0 ; discard return
%t21 = call ptr @PyDict_GetItem(ptr %dictvar, ptr @.str.7)
%t23 = call i32 @PyInt_AsI32(ptr %t21)
%t22 = call ptr @int2str(i32 %t23)
call void @print(ptr %t22)
%t24 = add i32 0, 0 ; discard return
ret i32 0
}
47 changes: 16 additions & 31 deletions src/lythonc/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,61 +12,46 @@ def main():
parser = ArgumentParser()

parser.add_argument(
"--emit-llvm",
"-emit-llvm",
help="Emit LLVM IR code",
metavar="<input-path>",
type=str
action='store_true'
)
parser.add_argument(
"--compile",
help="Compile Python code to machine code.",
nargs=2,
metavar=('<input-path>', '<output-path>'),
"-o",
help="Output file path",
metavar="<output-path>",
type=str
)
parser.add_argument(
"--dump-ast",
help="Dump the AST of the Python code",
"input_file",
help="Input Python file",
metavar="<input-path>",
type=str
)

args = parser.parse_args()

if not args.emit_llvm and not args.compile and not args.dump_ast:
if not args.emit_llvm and not args.o:
print("Error: No option provided")
parser.print_help()
sys.exit(1)

if args.emit_llvm:
input_file = args.emit_llvm
elif args.compile:
input_file = args.compile[0]
elif args.dump_ast:
input_file = args.dump_ast

if not os.path.exists(input_file):
print(f"Error: File '{input_file}' does not exist.")
if not os.path.exists(args.input_file):
print(f"Error: File '{args.input_file}' does not exist.")
parser.print_help()
sys.exit(1)

if args.emit_llvm:
print("Generate LLVM IR...")
codegen.generate_llvm(args.emit_llvm)
print(f"Generated LLVM IR code at {args.emit_llvm}.ll")
codegen.generate_llvm(args.input_file)
print(f"Generated LLVM IR code at {args.input_file}.ll")

elif args.compile:
input_file, output_file = args.compile
print(f"Compiling {input_file} to machine code...")
compiler.ll2bin.compile(input_file, output_file)
elif args.o:
output_file = args.o
print(f"Compiling {args.input_file} to machine code...")
compiler.ll2bin.compile(args.input_file, output_file)
print(f"Compiled Python code to machine code at {output_file}")

elif args.dump_ast:
print("The AST of the Python code is:")
with open(args.dump_ast) as f:
code = f.read()
print(codegen.dump_ast(code))

else:
print("Error: Invalid option provided.")
parser.print_help()
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.