Hello++/Compiler

From Esolang
Jump to navigation Jump to search

Propeng's Compiler

To compile using the Mono compiler, use mcs filename.cs.

using System;
using System.IO;
using System.CodeDom.Compiler;

namespace HelloPP
{
	class MainClass
	{
		public static string GenerateCode (string output)
		{
			return @"
using System;

namespace HelloPP
{
	class MainClass
	{
		public static void Main ()
		{
			Console.Write(@" + "\"" + output + "\"" + @");
		}
	}
}
";
		} // public static string GenerateCode
		
		public static void Main (string[] args)
		{
			string sourceFilename = string.Empty;
			string outputFilename = string.Empty;
			
			if (args.Length != 1 && args.Length != 2) {
				Console.WriteLine("Hello++ .NET Compiler by Propeng");
				Console.WriteLine("Usage: {0} <source> [destination]",
					Path.GetFileName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName));
				Environment.Exit(1);
			}
			
			if (args.Length == 1) {
				sourceFilename = args[0];
				outputFilename = "a.out";
			} else if (args.Length == 2) {
				sourceFilename = args[0];
				outputFilename = args[1];
			}
			
			if (Directory.Exists(sourceFilename)) {
				Console.WriteLine("{0}: Is a directory", sourceFilename);
				Environment.Exit(1);
			} else if (Directory.Exists(outputFilename)) {
				Console.WriteLine("{0}: Is a directory", outputFilename);
				Environment.Exit(1);
			}
			
			StreamReader reader;
			
			try {
				reader = new StreamReader(sourceFilename);
				
				char[] chars = reader.ReadToEnd().ToCharArray();
				string output = string.Empty;
				
				foreach (char sourceChar in chars) {
					if (sourceChar.ToString().ToLower() == "h")
						output += "Hello World" + Environment.NewLine;
				}
				
				System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
				parameters.GenerateExecutable = true;
				parameters.GenerateInMemory = false;
				parameters.OutputAssembly = outputFilename;
				
				try {
					CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("C#");
					CompilerResults results =
						codeProvider.CompileAssemblyFromSource(parameters, GenerateCode(output));
					
					foreach(CompilerError error in results.Errors) {
						Console.WriteLine(error.Line + ": " + error.ErrorNumber + " " + error.ErrorText);
					}
				} catch (Exception e) {
					Console.WriteLine("{0}: {1}", outputFilename, e.Message);
					Environment.Exit(1);
				}
			} catch (FileNotFoundException) {
				Console.WriteLine("{0}: No such file or directory", sourceFilename);
				Environment.Exit(1);
			} catch (IOException ioe) {
				Console.WriteLine("{0}: I/O Error", sourceFilename);
				Console.WriteLine(ioe.StackTrace);
				Environment.Exit(2);
			} catch (Exception une) {
				Console.WriteLine("{0}: {1}", sourceFilename, une.Message);
				Console.WriteLine(une.StackTrace);
				Environment.Exit(2);
			}
		} // public static void Main
	} // class MainClass
} // namespace HelloPP

Superstitionfreeblog's Compiler

A Hello++ compiler written in x86_64 assembly for Linux.

;   hpp.asm: A hello++ compiler.
;   usage: hpp [input] [output]
;   input and output can be files.
;   If input is "stdin", input is taken
;   from standard input.
;   If output is "stdout", ouput is to
;   standard output.
;   If no arguments, both input and output is
;   directed to standard input and output.
;   To compile: fasm hpp.asm hpp; chmod 755 hpp

format ELF64 executable 3
entry _start
segment readable executable
_start:
    xor r8, r8
    mov rbx, [rsp+16]
    or  rbx, rbx
    jz  .read
    mov ecx, [rbx]
    cmp ecx, "stdi"
    je  .read
    mov rax, 2
    mov rdi, rbx
    xor rsi, rsi
    syscall
    or  rax, rax
    js  .fnf
    mov [fd], rax
 .read:
    xor rax, rax
    mov rdi, [fd]
    mov rsi, buff
    mov rdx, 1
    syscall
    or  rax, rax
    jz  .create
    movzx rax, byte[buff]
    sub rax, 0x68
    jz @f
    movzx rax, byte[buff]
    sub rax, 0x48
    jz @f
    jmp .read
@@: inc r8d
    jmp .read
 .create:
    mov rbx, [rsp]
    sub rbx, 3
    jnz .write
    mov rbx, [rsp + 24]
    or  rbx, rbx
    jz  .write
    mov ecx, [rbx]
    cmp ecx, "stdo"
    je  .write
    mov rax, 85
    mov rdi, rbx
    mov rsi, 755o
    syscall
    or  rax, rax
    js  .fnc
    mov [fd+8], rax
 .write:
    mov dword[the_exe.count], r8d
    mov rax, 1
    mov rdi, [fd+8]
    mov rsi, the_exe
    movzx rdx, byte[len]
    syscall
 .exit:
    mov rdi, [fd]
    or  rdi, rdi
    jnz @f
    mov rax, 3
    syscall
@@:
    mov rdi, [fd+8]
    or  rdi, rdi
    cmp rdi, 1
    je @f
    mov rax, 3
    syscall
@@:
    mov rax, 60
    mov rdi, 0
    syscall
 .fnf:
    mov rax, 1
    mov rdi, 1
    mov rsi, fnf_msg
    movzx rdx, byte[fnf_msg.len]
    syscall
    jmp .exit
  .fnc:
    mov rax, 1
    mov rdi, 1
    mov rsi, fnc_msg
    movzx rdx, byte[fnc_msg.len]
    syscall
    jmp .exit

segment readable writable
buff:
    db '0'
fnf_msg:
    db "Error opening file.", 0x0a
 .len:
    db $ - fnf_msg
fnc_msg:
    db "Error creating file.", 0x0a
 .len:
    db $ - fnc_msg
fd:
    dq  0, 1
the_exe:
    db  0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x03
    db  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    db  0x02, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00
    db  0x78, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00
    db  0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    db  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    db  0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00
    db  0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00
    db  0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00
    db  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    db  0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00
    db  0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00
    db  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    db  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    db  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    db  0x48, 0xc7, 0xc1
 .count:
 ;This is the number of times to print "Hello, World!"
 ;We change this to the number of 'h' and 'H' in the input.
    dd  0
    db  0x48
    db  0x09, 0xc9, 0x74, 0x22, 0x48, 0xc7, 0xc0, 0x01
    db  0x00, 0x00, 0x00, 0x48, 0xc7, 0xc7, 0x01, 0x00
    db  0x00, 0x00, 0x48, 0xc7, 0xc6, 0xb2, 0x00, 0x40
    db  0x00, 0x48, 0xc7, 0xc2, 0x0c, 0x00, 0x00, 0x00
    db  0x51, 0x0f, 0x05, 0x59, 0xe2, 0xde, 0x48, 0xc7
    db  0xc0, 0x3c, 0x00, 0x00, 0x00, 0x48, 0x31, 0xff
    db  0x0f, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20
    db  0x57, 0x6f, 0x72, 0x6c, 0x64, 0x0a, 0x00, 0x00
len:
    db  $ - the_exe

Compiling and running:

~$ fasm hpp.asm hpp
flat assembler  version 1.73.30  (16384 kilobytes memory)
3 passes, 780 bytes.
~$ chmod 755 hpp
~$ echo "Hi! My honey's name is Howard" > h.txt
~$ cat h.txt
Hi! My honey's name is Howard
~$ ./hpp h.txt h
~$ ./h
Hello World
Hello World
Hello World
~$ echo "Hello World" | ./hpp stdin quine
~$ ./quine
Hello World
~$