...

Text file src/github.com/alecthomas/chroma/v2/lexers/testdata/stas.actual

Documentation: github.com/alecthomas/chroma/v2/lexers/testdata

     1include 'std.stas'
     2
     3reserve debug_symbols  1
     4reserve verbose_mode   1
     5auto    backend_type   1
     6
     7const StasBackend.fasm { 1 }
     8const StasBackend.nasm { 2 }
     9
    10; (StasBackend -- str len)
    11fn StasBackend.to_str 1 2 {
    12	dup StasBackend.fasm = if {
    13		"fasm"
    14	} elif dup StasBackend.nasm = {
    15		"nasm"
    16	} else {
    17		0 0 0 assert -> 'unreachable'
    18	}
    19	rot rot drop
    20}
    21
    22include 'src/stringbuffer.stas' ; handling strings
    23include 'src/tokens.stas'       ; stas token definitions
    24include 'src/util.stas'         ; utility functions, error handling
    25include 'src/scanner.stas'      ; lexer/scanner, creates tokens
    26include 'src/parserdefs.stas'   ; stas parser definitions, very large file
    27include 'src/eval.stas'         ; constant evaluation
    28include 'src/parser.stas'       ; stas parser, creates IR instructions
    29include 'src/write.stas'        ; buffers + writing to files
    30include 'src/dce.stas'          ; dead code elimination compiler pass
    31include 'src/x86.stas'          ; stas codegen definitions and reg allocator
    32include 'src/gen.stas'          ; stas code generator, creates x86_64 asm
    33
    34fn usage 0 0 {
    35	"stas 0.1.1 Copyright (C) 2022  l-m.dev\n\n"                                   eputs
    36	"USAGE: ./stas [OPTIONS] [FILE]\n\n"                                           eputs
    37
    38	"	-o <output>       Specify '-o -' to dump assembly to stdout\n"             eputs
    39	"	-g                Debug info. Most effective with the `nasm` backend\n"    eputs
    40	"	-b <backend>      Assemblers `nasm` or `fasm` as compiler backend\n"       eputs
    41	"	-r                Execute file after compiling. Arguments after this\n"    eputs
    42	"	                  switch will ignored and passed to the program\n"         eputs
    43	"	-v, --verbose     Activate verbose mode\n"                                 eputs
    44	"	--dump-tok        Dump token information after scanning stage\n"           eputs
    45	"	--dump-ir         Dump intermediate representation after parsing stage\n"  eputs
    46	"	-h, --help        Show this message\n\n"                                   eputs
    47}
    48
    49fn help_and_exit 0 0 {
    50	usage
    51	0 exit
    52}
    53
    54fn usage_and_exit 0 0 {
    55	usage
    56	1 exit
    57}
    58
    59fn usage_msg_and_exit 2 0 {
    60	error.generic_fatal_noexit
    61	usage_and_exit
    62}
    63
    64fn parse_backend_type 2 0 {
    65	over over "fasm" streq if {
    66		StasBackend.fasm pop backend_type
    67	} elif over over "nasm" streq {
    68		StasBackend.nasm pop backend_type
    69	} else {
    70		"unknown backend" usage_msg_and_exit
    71	}
    72	drop drop
    73}
    74
    75const sizeof(fasm_arg_buf) { sizeof(u64) 32 * }
    76
    77; (infile.str infile.len outfile.str outfile.len is_blocking)
    78fn execute_backend 5 0 {
    79	auto is_blocking 1 pop is_blocking
    80	auto outfile     2 pop outfile
    81	auto infile      2 pop infile
    82
    83	reserve arg_buf sizeof(fasm_arg_buf)
    84
    85	backend_type StasBackend.fasm = if {
    86		arg_buf       dup "fasm"    drop w64
    87		sizeof(u64) + dup infile    drop w64
    88		sizeof(u64) + dup outfile   drop w64
    89		sizeof(u64) + dup "-m"      drop w64
    90		sizeof(u64) + dup "1048576" drop w64
    91		sizeof(u64) +     NULL           w64
    92
    93		"/usr/bin/fasm"
    94	} elif backend_type StasBackend.nasm = {
    95		arg_buf       dup "nasm"    drop w64
    96		sizeof(u64) + dup infile    drop w64
    97		sizeof(u64) + dup "-o"      drop w64
    98		sizeof(u64) + dup outfile   drop w64
    99		sizeof(u64) + dup "-O0"     drop w64
   100		sizeof(u64) + dup "-felf64" drop w64
   101
   102		debug_symbols r8 if {
   103			sizeof(u64) + dup "-Fdwarf" drop w64
   104			sizeof(u64) + dup "-g"      drop w64
   105		}
   106
   107		sizeof(u64) +     NULL           w64
   108		"/usr/bin/nasm"
   109	}
   110
   111	verbose_mode r8 if {
   112		log.msg.start
   113		"`" eputs
   114			arg_buf argp_print
   115		"`\n" eputs	
   116	}
   117
   118	arg_buf is_blocking child_execve_and_shut_up
   119}
   120
   121const ArgParseMode.none    { 0 }
   122const ArgParseMode.output  { 1 }
   123const ArgParseMode.backend { 2 }
   124
   125fn main 0 0 {
   126	argc 1 = if {
   127		usage_and_exit
   128	}
   129
   130	reserve dump_ir   1
   131	reserve dump_tok  1
   132	reserve to_stdout 1
   133
   134	to_stdout      0 w8
   135	dump_ir        0 w8
   136	dump_tok       0 w8
   137
   138	auto run_exec_arg  1
   139	0 pop run_exec_arg
   140	
   141	UINT64_MAX       pop fwrite_buffer.fd_loc
   142	StasBackend.fasm pop backend_type            
   143
   144	auto argparse_mode 1
   145	auto argstr        2
   146
   147	auto out_file 2
   148	auto in_file  2
   149	NULL 0 pop out_file
   150	NULL 0 pop in_file
   151
   152	ArgParseMode.none pop argparse_mode
   153	debug_symbols false w8
   154
   155	1
   156	while dup argc < {
   157		dup args[] pop argstr
   158
   159		argstr "-o" streq if {
   160			argparse_mode ArgParseMode.none != if {
   161				usage_and_exit
   162			}
   163			ArgParseMode.output pop argparse_mode
   164		} elif argstr "-b" streq {
   165			argparse_mode ArgParseMode.none != if {
   166				usage_and_exit
   167			}
   168			ArgParseMode.backend pop argparse_mode
   169		} elif argstr "-g" streq {
   170			argparse_mode ArgParseMode.none != if {
   171				usage_and_exit
   172			}
   173			debug_symbols r8 if {
   174				usage_and_exit
   175			}
   176			debug_symbols true w8
   177		} elif argstr "--verbose" streq argstr "-v" streq | {
   178			argparse_mode ArgParseMode.none != if {
   179				usage_and_exit
   180			}
   181			verbose_mode r8 if {
   182				usage_and_exit
   183			}
   184			verbose_mode true w8
   185		} elif argstr "-r" streq {
   186			argparse_mode ArgParseMode.none != if {
   187				usage_and_exit
   188			}
   189			pop run_exec_arg
   190			argc
   191		} elif argstr "--help" streq argstr "-h" streq | {
   192			help_and_exit
   193		} elif argstr "--dump-ir" streq argstr "-h" streq | {
   194			argparse_mode ArgParseMode.none != dump_ir r8 | dump_tok r8 | if {
   195				usage_and_exit
   196			}
   197			dump_ir true w8
   198		} elif argstr "--dump-tok" streq argstr "-h" streq | {
   199			argparse_mode ArgParseMode.none != dump_ir r8 | dump_tok r8 | if {
   200				usage_and_exit
   201			}
   202			dump_tok true w8
   203		} else {
   204			argparse_mode ArgParseMode.none = if {
   205				in_file drop NULL != if {
   206					usage_and_exit
   207				}
   208				argstr pop in_file
   209			} elif argparse_mode ArgParseMode.output = {
   210				out_file drop NULL != if {
   211					usage_and_exit
   212				}
   213				argstr pop out_file
   214			} elif argparse_mode ArgParseMode.backend = {
   215				argstr parse_backend_type
   216			} else {
   217				0 assert
   218			}
   219			ArgParseMode.none pop argparse_mode
   220		}
   221		++
   222	}
   223	drop
   224
   225	argparse_mode ArgParseMode.none != if {
   226		argparse_mode ArgParseMode.output = if {
   227			"supply output file" usage_msg_and_exit
   228		} elif argparse_mode ArgParseMode.backend = {
   229			"supply backend type" usage_msg_and_exit
   230		}
   231	}
   232
   233	in_file drop NULL = if {
   234		"supply stas file" usage_msg_and_exit
   235	}
   236
   237	out_file drop NULL = if {
   238		debug_symbols r8 backend_type StasBackend.nasm = | if {
   239			"a.o"
   240		} else {
   241			"a.out"
   242		}
   243		pop out_file
   244	} else {
   245		out_file "-" streq if {
   246			to_stdout true w8
   247		}
   248	}
   249
   250	verbose_mode r8 if {
   251		log.msg.start
   252		"scanning file `" eputs in_file eputs "`\n" eputs
   253	}
   254	
   255	log.time.start
   256		in_file stas.scan_file
   257	"scanning took " log.time.end
   258
   259	dump_tok r8 if {
   260		token_stream.dump
   261		ret
   262	}
   263
   264	verbose_mode r8 if {
   265		log.msg.start
   266		"parsing " eputs token_stream.len eputu " tokens\n" eputs
   267	}
   268	log.time.start
   269		stas.parse
   270	"parsing took " log.time.end
   271	verbose_mode r8 if {
   272		log.msg.start
   273		functions.len eputu " functions, " eputs label_c ++ eputu " labels\n" eputs
   274		log.msg.start
   275		global_var_context.len eputu " global variables, " eputs toplevel_constants.len eputu " constants\n" eputs
   276	}
   277	
   278	dump_ir r8 if {
   279		ir_stream.dump
   280		ret
   281	}
   282
   283	verbose_mode r8 if {
   284		log.msg.start
   285		"dce pass started\n" eputs
   286	}
   287	log.time.start
   288		stas.dce
   289	"dce took " log.time.end
   290	verbose_mode r8 if {
   291		log.msg.start
   292		used_functions eputu " used functions, of which " eputs inlined_functions eputu " are eligible for inline\n" eputs
   293		log.msg.start
   294		slits.len eputu " string literals\n" eputs
   295	}
   296	
   297	auto out_file_asm_sv 1 
   298
   299	to_stdout r8 ! if {
   300		out_file new_string_view
   301		dup ".tmp" push_string_view
   302		dup pop out_file_asm_sv
   303
   304		string_view_to_str fd_new_file_for_writing
   305		pop fwrite_buffer.fd_loc
   306	} else {
   307		stdout pop fwrite_buffer.fd_loc
   308	}
   309
   310	verbose_mode r8 if {
   311		log.msg.start
   312		"generating code from " eputs ir_stream.len eputu " IR instructions\n" eputs
   313	}
   314	log.time.start
   315		in_file stas.gen
   316	"gen took " log.time.end
   317
   318	to_stdout r8 if {
   319		ret
   320	}
   321	verbose_mode r8 if {
   322		log.msg.start
   323		"generated " eputs
   324
   325		fwrite_buffer.fd_loc fd_stat_size
   326
   327		dup 1024 / 0 > if {
   328			eputu " KiBs of code\n" eputs
   329		} else {
   330			eputu " bytes of code\n" eputs
   331		}
   332	}
   333
   334	fwrite_buffer.fd_loc close 0 <s if {
   335		"FATAL: Failed to close file descriptor\n" eputs
   336		1 exit
   337	}
   338	verbose_mode r8 if {
   339		log.msg.start
   340		"wrote code to `" eputs out_file_asm_sv string_view_to_str eputs "`\n" eputs
   341	}
   342
   343	verbose_mode r8 if {
   344		log.msg.start
   345		"executing assembler backend `" eputs backend_type StasBackend.to_str eputs "`\n" eputs
   346	}
   347
   348	log.time.start
   349		out_file_asm_sv string_view_to_str out_file run_exec_arg 0 != execute_backend
   350	"backend took " log.time.end
   351	
   352	verbose_mode r8 if {
   353		log.msg.start
   354		"created binary `" eputs out_file eputs "`\n" eputs
   355	}
   356
   357	debug_symbols r8 backend_type StasBackend.nasm = | if {
   358		ret
   359	}
   360
   361	run_exec_arg 0 != if {
   362		reserve null_p sizeof(u64)
   363		null_p NULL w64
   364
   365		auto argp 1
   366
   367		{
   368			string_buffer string_buffer.len + pop argp
   369
   370			out_file drop string_buffer.generic_append_u64
   371
   372			run_exec_arg 1 +
   373			while dup argc < {
   374				dup sizeof(u64) * argv + r64 string_buffer.generic_append_u64
   375				++
   376			}
   377			drop
   378
   379			NULL string_buffer.generic_append_u64
   380		}
   381
   382		out_file drop
   383		argp
   384		null_p
   385
   386		verbose_mode r8 if {
   387			log.msg.start
   388			
   389			"exceve binary `" eputs 
   390
   391			argp
   392			argp_print
   393
   394			"`\n" eputs
   395		}
   396		
   397		execve 0 <s if {
   398			"FATAL: Could not execve file\n" eputs
   399			1 exit
   400		}
   401	}
   402}

View as plain text